|
47791
|
1698
|
21
|
2026-05-15T08:53:09.043941+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835189043_m1.jpg...
|
Firefox
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira — Work...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Space navigation
Space navigation
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Space navigation","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Space navigation","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":11,"on_screen":true,"help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","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":"Recent","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Starred","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":"Starred","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","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":"Apps","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Apps","depth":13,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Apps","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Spaces","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Spaces","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create space","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create space","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for spaces","depth":13,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for spaces","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recent","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny (New)","depth":17,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny (New)","depth":20,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Jiminny (New)","depth":18,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXMenuButton","text":"Create board","depth":18,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create board","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Jiminny (New)","depth":18,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Jiminny (New)","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform Team","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Team","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Capture Team","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Capture Team","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
6885244539695223455
|
4203298456818570412
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Space navigation
Space navigation
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47792
|
1699
|
30
|
2026-05-15T08:53:09.075807+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835189075_m2.jpg...
|
Firefox
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira — Work...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Space navigation
Space navigation
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.05905826,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.2252327,"top":0.38068634,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"bounds":{"left":0.31266624,"top":0.07861133,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Space navigation","depth":10,"bounds":{"left":0.31266624,"top":0.15522745,"width":0.037898935,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Space navigation","depth":11,"bounds":{"left":0.31266624,"top":0.15522745,"width":0.037898935,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"bounds":{"left":0.30601728,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"bounds":{"left":0.31117022,"top":0.06344773,"width":0.039727394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"bounds":{"left":0.3179854,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"bounds":{"left":0.3231383,"top":0.06344773,"width":0.044215426,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"bounds":{"left":0.33128324,"top":0.057861134,"width":0.029421542,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":11,"bounds":{"left":0.5159575,"top":0.06264964,"width":0.24268617,"height":0.015961692},"on_screen":true,"help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"bounds":{"left":0.7669548,"top":0.057861134,"width":0.030086435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"bounds":{"left":0.77825797,"top":0.06384677,"width":0.014793883,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"bounds":{"left":0.91223407,"top":0.057861134,"width":0.035904255,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"bounds":{"left":0.92353725,"top":0.06384677,"width":0.020611702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"bounds":{"left":0.9494681,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"bounds":{"left":0.954621,"top":0.06344773,"width":0.027759308,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"bounds":{"left":0.96143615,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"bounds":{"left":0.9665891,"top":0.06344773,"width":0.010139627,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"bounds":{"left":0.9734042,"top":0.080207504,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.97855717,"top":0.08579409,"width":0.017952127,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.98537236,"top":0.080207504,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"bounds":{"left":0.99052525,"top":0.08579409,"width":0.009474754,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"bounds":{"left":0.30601728,"top":0.12210695,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"bounds":{"left":0.31665558,"top":0.12809257,"width":0.01662234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"bounds":{"left":0.30601728,"top":0.14764565,"width":0.071476065,"height":0.025538707},"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":"Recent","depth":15,"bounds":{"left":0.31665558,"top":0.15363128,"width":0.015458777,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Starred","depth":12,"bounds":{"left":0.30601728,"top":0.17318435,"width":0.071476065,"height":0.025538707},"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":"Starred","depth":15,"bounds":{"left":0.31665558,"top":0.17917,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","depth":12,"bounds":{"left":0.30601728,"top":0.19872306,"width":0.071476065,"height":0.025538707},"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":"Apps","depth":15,"bounds":{"left":0.31665558,"top":0.2047087,"width":0.011635638,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Apps","depth":13,"bounds":{"left":0.37549868,"top":0.2019154,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Apps","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Spaces","depth":12,"bounds":{"left":0.30601728,"top":0.22426178,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Spaces","depth":15,"bounds":{"left":0.31665558,"top":0.23024741,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
4032195781546253243
|
-6321613902444725108
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Space navigation
Space navigation
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces...
|
47790
|
NULL
|
NULL
|
NULL
|
|
47793
|
1699
|
31
|
2026-05-15T08:53:10.232183+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835190232_m2.jpg...
|
Firefox
|
Work — Mozilla Firefox
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
New Tab
New Tab
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
22°
C
New York City
Open menu
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Open context menu for Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Jiminny
Jiminny
Open context menu for Jiminny
Pipelines - jiminny/app
Pipelines - jiminny/app
Open context menu for Pipelines - jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Open context menu for JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Inbox (1,684) - [EMAIL] - Jiminny Mail
Inbox (1,684) - [EMAIL] - Jiminny Mail
Open context menu for Inbox (1,684) - [EMAIL] - Jiminny Mail
Userpilot | Events
Userpilot | Events
Open context menu for Userpilot | Events
503 Service Temporarily Unavailable
503 Service Temporarily Unavailable
Open context menu for 503 Service Temporarily Unavailable
Jiminny
Jiminny
Open context menu for Jiminny
Customize
Customize...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.074221864,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.08539505,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.10694334,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.11811652,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.1396648,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.15083799,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.17238627,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.18355946,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.20510775,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.21628092,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.23782921,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.2490024,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.27055067,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.28172386,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.30327216,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.31444532,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.33599362,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.3471668,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.36871508,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.37988827,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.22240691,"top":0.40143654,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.2357048,"top":0.41260973,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.4086193,"width":0.007978723,"height":0.01915403},"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.2252327,"top":0.43575418,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"22°","depth":8,"bounds":{"left":0.94148934,"top":0.10415004,"width":0.00930851,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"C","depth":8,"bounds":{"left":0.95079786,"top":0.10415004,"width":0.0039893617,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"New York City","depth":8,"bounds":{"left":0.94148934,"top":0.12051077,"width":0.02825798,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open menu","depth":7,"bounds":{"left":0.9734042,"top":0.0981644,"width":0.01662234,"height":0.043894652},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Mozilla Firefox","depth":8,"bounds":{"left":0.4331782,"top":0.40782124,"width":0.43583778,"height":0.051077414},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Search with Google or enter address","depth":8,"bounds":{"left":0.53141624,"top":0.4828412,"width":0.2393617,"height":0.0415004},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search with Google or enter address","depth":10,"bounds":{"left":0.54787236,"top":0.4960096,"width":0.08344415,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":11,"bounds":{"left":0.4915226,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":13,"bounds":{"left":0.49617687,"top":0.61731845,"width":0.030418882,"height":0.06384677},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":11,"bounds":{"left":0.5234375,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Jiminny","depth":11,"bounds":{"left":0.53141624,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":13,"bounds":{"left":0.54355055,"top":0.61731845,"width":0.015458777,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Jiminny","depth":11,"bounds":{"left":0.5633311,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Pipelines - jiminny/app","depth":11,"bounds":{"left":0.57130986,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":13,"bounds":{"left":0.57978725,"top":0.61731845,"width":0.022772606,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Pipelines - jiminny/app","depth":11,"bounds":{"left":0.60322475,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":11,"bounds":{"left":0.61120343,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":13,"bounds":{"left":0.6165226,"top":0.61731845,"width":0.029089095,"height":0.10215483},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":11,"bounds":{"left":0.6431183,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Inbox (1,684) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":11,"bounds":{"left":0.65109706,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox (1,684) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":13,"bounds":{"left":0.65575135,"top":0.61731845,"width":0.030418882,"height":0.051077414},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Inbox (1,684) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":11,"bounds":{"left":0.68301195,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Userpilot | Events","depth":11,"bounds":{"left":0.6909907,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Userpilot | Events","depth":13,"bounds":{"left":0.7006317,"top":0.61731845,"width":0.02044548,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Userpilot | Events","depth":11,"bounds":{"left":0.7229056,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"503 Service Temporarily Unavailable","depth":11,"bounds":{"left":0.7308843,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"503 Service Temporarily Unavailable","depth":13,"bounds":{"left":0.7386968,"top":0.61731845,"width":0.024102394,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for 503 Service Temporarily Unavailable","depth":11,"bounds":{"left":0.7627992,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Jiminny","depth":11,"bounds":{"left":0.77077794,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":13,"bounds":{"left":0.78291225,"top":0.61731845,"width":0.015458777,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Jiminny","depth":11,"bounds":{"left":0.80269283,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Customize","depth":8,"bounds":{"left":0.97955453,"top":0.9509178,"width":0.012965426,"height":0.0311253},"on_screen":true,"help_text":"Customize this page","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customize","depth":10,"bounds":{"left":0.98271275,"top":0.95929766,"width":0.017287254,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-5512045330760734450
|
-4867023801325557561
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
New Tab
New Tab
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
22°
C
New York City
Open menu
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Open context menu for Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Jiminny
Jiminny
Open context menu for Jiminny
Pipelines - jiminny/app
Pipelines - jiminny/app
Open context menu for Pipelines - jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Open context menu for JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Inbox (1,684) - [EMAIL] - Jiminny Mail
Inbox (1,684) - [EMAIL] - Jiminny Mail
Open context menu for Inbox (1,684) - [EMAIL] - Jiminny Mail
Userpilot | Events
Userpilot | Events
Open context menu for Userpilot | Events
503 Service Temporarily Unavailable
503 Service Temporarily Unavailable
Open context menu for 503 Service Temporarily Unavailable
Jiminny
Jiminny
Open context menu for Jiminny
Customize
Customize...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47794
|
1698
|
22
|
2026-05-15T08:53:10.977161+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835190977_m1.jpg...
|
Firefox
|
Work — Mozilla Firefox
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
New Tab
New Tab
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
22°
C
New York City
Open menu
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Open context menu for Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Jiminny
Jiminny
Open context menu for Jiminny
Pipelines - jiminny/app
Pipelines - jiminny/app
Open context menu for Pipelines - jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Open context menu for JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Inbox (1,684) - [EMAIL] - Jiminny Mail
Inbox (1,684) - [EMAIL] - Jiminny Mail
Open context menu for Inbox (1,684) - [EMAIL] - Jiminny Mail
Userpilot | Events
Userpilot | Events
Open context menu for Userpilot | Events
503 Service Temporarily Unavailable
503 Service Temporarily Unavailable
Open context menu for 503 Service Temporarily Unavailable
Jiminny
Jiminny
Open context menu for Jiminny
Customize
Customize
github.com/jiminny/app/pull/11932...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"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,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"22°","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"C","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"New York City","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open menu","depth":7,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Mozilla Firefox","depth":8,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Search with Google or enter address","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search with Google or enter address","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Jiminny","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Jiminny","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Pipelines - jiminny/app","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Pipelines - jiminny/app","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Inbox (1,684) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox (1,684) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Inbox (1,684) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Userpilot | Events","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Userpilot | Events","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Userpilot | Events","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"503 Service Temporarily Unavailable","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"503 Service Temporarily Unavailable","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for 503 Service Temporarily Unavailable","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Jiminny","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Jiminny","depth":11,"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Customize","depth":8,"on_screen":true,"help_text":"Customize this page","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customize","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"github.com/jiminny/app/pull/11932","depth":5,"bounds":{"left":0.06909722,"top":0.0,"width":0.123958334,"height":0.015},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
179114868808606779
|
-4867164540969785145
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
New Tab
New Tab
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
22°
C
New York City
Open menu
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Open context menu for Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Jiminny
Jiminny
Open context menu for Jiminny
Pipelines - jiminny/app
Pipelines - jiminny/app
Open context menu for Pipelines - jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Open context menu for JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Inbox (1,684) - [EMAIL] - Jiminny Mail
Inbox (1,684) - [EMAIL] - Jiminny Mail
Open context menu for Inbox (1,684) - [EMAIL] - Jiminny Mail
Userpilot | Events
Userpilot | Events
Open context menu for Userpilot | Events
503 Service Temporarily Unavailable
503 Service Temporarily Unavailable
Open context menu for 503 Service Temporarily Unavailable
Jiminny
Jiminny
Open context menu for Jiminny
Customize
Customize
github.com/jiminny/app/pull/11932...
|
47791
|
NULL
|
NULL
|
NULL
|
|
47795
|
1699
|
32
|
2026-05-15T08:53:10.977177+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835190977_m2.jpg...
|
Firefox
|
Work — Mozilla Firefox
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
New Tab
New Tab
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
22°
C
New York City
Open menu
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Open context menu for Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Jiminny
Jiminny
Open context menu for Jiminny
Pipelines - jiminny/app
Pipelines - jiminny/app
Open context menu for Pipelines - jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Open context menu for JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Inbox (1,684) - [EMAIL] - Jiminny Mail
Inbox (1,684) - [EMAIL] - Jiminny Mail
Open context menu for Inbox (1,684) - [EMAIL] - Jiminny Mail
Userpilot | Events
Userpilot | Events
Open context menu for Userpilot | Events
503 Service Temporarily Unavailable
503 Service Temporarily Unavailable
Open context menu for 503 Service Temporarily Unavailable
Jiminny
Jiminny
Open context menu for Jiminny
Customize
Customize
github.com/jiminny/app/pull/11932...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.074221864,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.08539505,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.10694334,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.11811652,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.1396648,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.15083799,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.17238627,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.18355946,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.20510775,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.21628092,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.23782921,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.2490024,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.27055067,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.28172386,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.30327216,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.31444532,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.33599362,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.3471668,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.36871508,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.37988827,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.22240691,"top":0.40143654,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.2357048,"top":0.41260973,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.4086193,"width":0.007978723,"height":0.01915403},"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.2252327,"top":0.43575418,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"22°","depth":8,"bounds":{"left":0.94148934,"top":0.10415004,"width":0.00930851,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"C","depth":8,"bounds":{"left":0.95079786,"top":0.10415004,"width":0.0039893617,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"New York City","depth":8,"bounds":{"left":0.94148934,"top":0.12051077,"width":0.02825798,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open menu","depth":7,"bounds":{"left":0.9734042,"top":0.0981644,"width":0.01662234,"height":0.043894652},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Mozilla Firefox","depth":8,"bounds":{"left":0.4331782,"top":0.40782124,"width":0.43583778,"height":0.051077414},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Search with Google or enter address","depth":8,"bounds":{"left":0.53141624,"top":0.4828412,"width":0.2393617,"height":0.0415004},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search with Google or enter address","depth":10,"bounds":{"left":0.54787236,"top":0.4960096,"width":0.08344415,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":11,"bounds":{"left":0.4915226,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":13,"bounds":{"left":0.49617687,"top":0.61731845,"width":0.030418882,"height":0.06384677},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":11,"bounds":{"left":0.5234375,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Jiminny","depth":11,"bounds":{"left":0.53141624,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":13,"bounds":{"left":0.54355055,"top":0.61731845,"width":0.015458777,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Jiminny","depth":11,"bounds":{"left":0.5633311,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Pipelines - jiminny/app","depth":11,"bounds":{"left":0.57130986,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":13,"bounds":{"left":0.57978725,"top":0.61731845,"width":0.022772606,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Pipelines - jiminny/app","depth":11,"bounds":{"left":0.60322475,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":11,"bounds":{"left":0.61120343,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":13,"bounds":{"left":0.6165226,"top":0.61731845,"width":0.029089095,"height":0.10215483},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":11,"bounds":{"left":0.6431183,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Inbox (1,684) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":11,"bounds":{"left":0.65109706,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox (1,684) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":13,"bounds":{"left":0.65575135,"top":0.61731845,"width":0.030418882,"height":0.051077414},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Inbox (1,684) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":11,"bounds":{"left":0.68301195,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Userpilot | Events","depth":11,"bounds":{"left":0.6909907,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Userpilot | Events","depth":13,"bounds":{"left":0.7006317,"top":0.61731845,"width":0.02044548,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Userpilot | Events","depth":11,"bounds":{"left":0.7229056,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"503 Service Temporarily Unavailable","depth":11,"bounds":{"left":0.7308843,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"503 Service Temporarily Unavailable","depth":13,"bounds":{"left":0.7386968,"top":0.61731845,"width":0.024102394,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for 503 Service Temporarily Unavailable","depth":11,"bounds":{"left":0.7627992,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Jiminny","depth":11,"bounds":{"left":0.77077794,"top":0.5482841,"width":0.039893616,"height":0.09736632},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":13,"bounds":{"left":0.78291225,"top":0.61731845,"width":0.015458777,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open context menu for Jiminny","depth":11,"bounds":{"left":0.80269283,"top":0.55706304,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"Open menu","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Customize","depth":8,"bounds":{"left":0.97955453,"top":0.9509178,"width":0.012965426,"height":0.0311253},"on_screen":true,"help_text":"Customize this page","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customize","depth":10,"bounds":{"left":0.98271275,"top":0.95929766,"width":0.017287254,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"github.com/jiminny/app/pull/11932","depth":5,"bounds":{"left":0.30335772,"top":0.9876297,"width":0.059341755,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
179114868808606779
|
-4867164540969785145
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
New Tab
New Tab
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
22°
C
New York City
Open menu
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Open context menu for Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Jiminny
Jiminny
Open context menu for Jiminny
Pipelines - jiminny/app
Pipelines - jiminny/app
Open context menu for Pipelines - jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Open context menu for JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Inbox (1,684) - [EMAIL] - Jiminny Mail
Inbox (1,684) - [EMAIL] - Jiminny Mail
Open context menu for Inbox (1,684) - [EMAIL] - Jiminny Mail
Userpilot | Events
Userpilot | Events
Open context menu for Userpilot | Events
503 Service Temporarily Unavailable
503 Service Temporarily Unavailable
Open context menu for 503 Service Temporarily Unavailable
Jiminny
Jiminny
Open context menu for Jiminny
Customize
Customize
github.com/jiminny/app/pull/11932...
|
47793
|
NULL
|
NULL
|
NULL
|
|
47796
|
1699
|
33
|
2026-05-15T08:53:13.279005+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835193279_m2.jpg...
|
Firefox
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app — Work...
|
1
|
github.com/jiminny/app/pull/11932
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have no unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
JY-20543 add AJ reports User pilot tracking #11932 Edit title
JY-20543 add AJ reports User pilot tracking
#
11932
Edit title
Code
Code
Merged
LakyLak
LakyLak
merged 6 commits into
JY-18909-automated-reports-ask-jiminny
JY-18909-automated-reports-ask-jiminny
from
JY-20543-AJ-report-tracking
JY-20543-AJ-report-tracking
Copy head branch name to clipboard
on Apr 15
Lines changed: 284 additions & 1 deletion
Conversation
Conversation
Commits (6)
Commits
(
6
)
Checks
Checks
Files changed
Files changed
Conversation
Conversation
@LakyLak
Show options
LakyLak commented on Apr 9
LakyLak
LakyLak
commented
on Apr 9
on Apr 9
No description provided.
Add or remove reactions
LakyLak
LakyLak
added
4
commits
last month
last month
@LakyLak
JY-20543
JY-20543
add AJ reports User pilot tracking
add AJ reports User pilot tracking
609200a
609200a
@LakyLak
JY-20543
JY-20543
code smells
code smells
21ab308
21ab308
@LakyLak
JY-20543
JY-20543
fix test
fix test
93a69eb
93a69eb
@LakyLak
JY-20543
JY-20543
fix event
fix event
01241ae
01241ae
@LakyLak
LakyLak
LakyLak
requested review from
Vasil-Jiminny
Vasil-Jiminny
,
nikolaybiaivanov
nikolaybiaivanov
and
yalokin-jiminny
yalokin-jiminny
last month
last month
nikolaybiaivanov
nikolaybiaivanov
nikolaybiaivanov
approved these changes
on Apr 9
on Apr 9
View reviewed changes
View reviewed changes
@yalokin-jiminny
Show options
yalokin-jiminny commented on Apr 9
yalokin-jiminny
yalokin-jiminny
commented
on Apr 9
on Apr 9
@claude
@claude
Add or remove reactions
react with eyes
👀
1
@claude
Show options
claude Bot commented on Apr 9 •
claude
claude
Bot
commented
on Apr 9
on Apr 9
•
edited
edited
Claude finished
@yalokin-jiminny
@yalokin-jiminny
's task in 1m 11s
——
View job
View job
Code Review
Code Review
Completed task
Gather context
Completed task
Read changed files
Completed task
Analyze code and provide review feedback
Overall the implementation is clean and well-structured. Good use of the event/listener pattern, proper queuing via
ShouldQueue
, and solid test coverage. A few things worth flagging:
Issues
Issues
1. Silent error swallowing — no logging on
GuzzleException
app/Listeners/AutomatedReports/UserPilot/TrackAutomatedReportGeneratedEvent.php
L44–45
}
catch
(GuzzleException
$
e
) {
$...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.15924202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.38627294,"width":0.007978723,"height":0.01915403},"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.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.3020279,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.3020279,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.3073471,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.32197472,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.3352726,"top":0.06464485,"width":0.018949468,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.33726728,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.35920876,"top":0.06464485,"width":0.017785905,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.36120346,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have no unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.30169547,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.30169547,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.3073471,"top":0.09936153,"width":0.025099734,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.3181516,"top":0.10574621,"width":0.011469414,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"bounds":{"left":0.33510637,"top":0.09936153,"width":0.05518617,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.34574467,"top":0.10574621,"width":0.02925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.3776596,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"bounds":{"left":0.3806516,"top":0.113727055,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.38646942,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.3929521,"top":0.09936153,"width":0.029089095,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.4039229,"top":0.10574621,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.4247008,"top":0.09936153,"width":0.03025266,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.43583778,"top":0.10574621,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.45761302,"top":0.09936153,"width":0.022938829,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.46841756,"top":0.10574621,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"bounds":{"left":0.48321143,"top":0.09936153,"width":0.05817819,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.4950133,"top":0.10574621,"width":0.04255319,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.5440492,"top":0.09936153,"width":0.03125,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.55518615,"top":0.10574621,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.57795876,"top":0.09936153,"width":0.032081116,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.5890958,"top":0.10574621,"width":0.01761968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.31565824,"top":0.14365523,"width":0.0003324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.039228722,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.2159242,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.57214093,"top":0.1452514,"width":0.08261303,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.70694816,"top":0.1452514,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.13886672,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"JY-20543 add AJ reports User pilot tracking #11932 Edit title","depth":13,"bounds":{"left":0.44896942,"top":0.19193934,"width":0.25116357,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking","depth":14,"bounds":{"left":0.44896942,"top":0.19273743,"width":0.20162898,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":15,"bounds":{"left":0.65325797,"top":0.19273743,"width":0.006482713,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11932","depth":15,"bounds":{"left":0.6597407,"top":0.19273743,"width":0.028424202,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit title","depth":14,"bounds":{"left":0.68949467,"top":0.19513169,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Code","depth":13,"bounds":{"left":0.8249667,"top":0.19832402,"width":0.02825798,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Code","depth":15,"bounds":{"left":0.82928854,"top":0.20430966,"width":0.011635638,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merged","depth":13,"bounds":{"left":0.45960772,"top":0.23623304,"width":0.017121011,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":15,"bounds":{"left":0.48337767,"top":0.2330407,"width":0.01861702,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":16,"bounds":{"left":0.48337767,"top":0.23463687,"width":0.01861702,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"merged 6 commits into","depth":15,"bounds":{"left":0.50332445,"top":0.23463687,"width":0.049700797,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-18909-automated-reports-ask-jiminny","depth":15,"bounds":{"left":0.554355,"top":0.23264167,"width":0.09507979,"height":0.017557861},"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-18909-automated-reports-ask-jiminny","depth":16,"bounds":{"left":0.55634975,"top":0.235834,"width":0.091090426,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":16,"bounds":{"left":0.65076464,"top":0.23463687,"width":0.009973404,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20543-AJ-report-tracking","depth":16,"bounds":{"left":0.66206783,"top":0.23264167,"width":0.06881649,"height":0.017557861},"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543-AJ-report-tracking","depth":17,"bounds":{"left":0.6640625,"top":0.235834,"width":0.06482713,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":16,"bounds":{"left":0.7322141,"top":0.23024741,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"on Apr 15","depth":16,"bounds":{"left":0.7428524,"top":0.23463687,"width":0.02044548,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lines changed: 284 additions & 1 deletion","depth":14,"bounds":{"left":0.8211436,"top":0.28651237,"width":0.019946808,"height":0.11412609},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Conversation","depth":16,"bounds":{"left":0.44896942,"top":0.26855546,"width":0.044714097,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Conversation","depth":17,"bounds":{"left":0.46126994,"top":0.27813247,"width":0.028091755,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Commits (6)","depth":16,"bounds":{"left":0.49368352,"top":0.26855546,"width":0.045711435,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Commits","depth":17,"bounds":{"left":0.50598407,"top":0.27813247,"width":0.019115692,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.53507316,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6","depth":18,"bounds":{"left":0.53806514,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.54105717,"top":0.27813247,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Checks","depth":16,"bounds":{"left":0.539395,"top":0.26855546,"width":0.032579787,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Checks","depth":17,"bounds":{"left":0.55169547,"top":0.27813247,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Files changed","depth":16,"bounds":{"left":0.57197475,"top":0.26855546,"width":0.04637633,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Files changed","depth":17,"bounds":{"left":0.58427525,"top":0.27813247,"width":0.029753989,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Conversation","depth":12,"bounds":{"left":0.44896942,"top":0.3140463,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation","depth":13,"bounds":{"left":0.44896942,"top":0.31683958,"width":0.048204787,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.44896942,"top":0.3140463,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":15,"bounds":{"left":0.72257316,"top":0.31484437,"width":0.007978723,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"LakyLak commented on Apr 9","depth":14,"bounds":{"left":0.47323802,"top":0.31484437,"width":0.24135639,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":16,"bounds":{"left":0.47323802,"top":0.32282522,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":17,"bounds":{"left":0.47323802,"top":0.32282522,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":15,"bounds":{"left":0.49301863,"top":0.32282522,"width":0.025598405,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"on Apr 9","depth":15,"bounds":{"left":0.5199468,"top":0.32122904,"width":0.018450798,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"on Apr 9","depth":17,"bounds":{"left":0.5199468,"top":0.32282522,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No description provided.","depth":18,"bounds":{"left":0.47323802,"top":0.35953712,"width":0.05285904,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":16,"bounds":{"left":0.47323802,"top":0.38747007,"width":0.008643617,"height":0.0207502},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"LakyLak","depth":14,"bounds":{"left":0.48121676,"top":0.45291302,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":15,"bounds":{"left":0.48121676,"top":0.45291302,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"added","depth":14,"bounds":{"left":0.49966756,"top":0.45291302,"width":0.016289894,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":14,"bounds":{"left":0.5159575,"top":0.45291302,"width":0.0028257978,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commits","depth":14,"bounds":{"left":0.5187833,"top":0.45291302,"width":0.020944148,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"last month","depth":14,"bounds":{"left":0.5397274,"top":0.45291302,"width":0.022772606,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"last month","depth":16,"bounds":{"left":0.5397274,"top":0.45291302,"width":0.022772606,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.48121676,"top":0.49281725,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"bounds":{"left":0.4898604,"top":0.4964086,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543","depth":15,"bounds":{"left":0.4898604,"top":0.4964086,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"add AJ reports User pilot tracking","depth":14,"bounds":{"left":0.5113032,"top":0.4964086,"width":0.081615694,"height":0.011572227},"on_screen":true,"help_text":"JY-20543 add AJ reports User pilot tracking","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"add AJ reports User pilot tracking","depth":15,"bounds":{"left":0.5113032,"top":0.4964086,"width":0.081615694,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"609200a","depth":14,"bounds":{"left":0.71924865,"top":0.4964086,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"609200a","depth":15,"bounds":{"left":0.71924865,"top":0.4964086,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.48121676,"top":0.5343176,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"bounds":{"left":0.4898604,"top":0.53790903,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543","depth":15,"bounds":{"left":0.4898604,"top":0.53790903,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"code smells","depth":14,"bounds":{"left":0.5113032,"top":0.53790903,"width":0.02642952,"height":0.011572227},"on_screen":true,"help_text":"JY-20543 code smells","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"code smells","depth":15,"bounds":{"left":0.5113032,"top":0.53790903,"width":0.02642952,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"21ab308","depth":14,"bounds":{"left":0.71924865,"top":0.53790903,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"21ab308","depth":15,"bounds":{"left":0.71924865,"top":0.53790903,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.48121676,"top":0.56304866,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"bounds":{"left":0.4898604,"top":0.5666401,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543","depth":15,"bounds":{"left":0.4898604,"top":0.5666401,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"fix test","depth":14,"bounds":{"left":0.5113032,"top":0.5666401,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"JY-20543 fix test","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix test","depth":15,"bounds":{"left":0.5113032,"top":0.5666401,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"93a69eb","depth":14,"bounds":{"left":0.71924865,"top":0.5666401,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"93a69eb","depth":15,"bounds":{"left":0.71924865,"top":0.5666401,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.48121676,"top":0.5917797,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"bounds":{"left":0.4898604,"top":0.5953711,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543","depth":15,"bounds":{"left":0.4898604,"top":0.5953711,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"fix event","depth":14,"bounds":{"left":0.5113032,"top":0.5953711,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"JY-20543 fix event","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix event","depth":15,"bounds":{"left":0.5113032,"top":0.5953711,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"01241ae","depth":14,"bounds":{"left":0.71924865,"top":0.5953711,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"01241ae","depth":15,"bounds":{"left":0.71924865,"top":0.5953711,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":14,"bounds":{"left":0.48121676,"top":0.64285713,"width":0.0066489363,"height":0.017956903},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"LakyLak","depth":14,"bounds":{"left":0.48902926,"top":0.6444533,"width":0.01861702,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":15,"bounds":{"left":0.48902926,"top":0.6444533,"width":0.01861702,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"requested review from","depth":14,"bounds":{"left":0.50764626,"top":0.6444533,"width":0.05086436,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":14,"bounds":{"left":0.55851066,"top":0.6444533,"width":0.03025266,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":15,"bounds":{"left":0.55851066,"top":0.6444533,"width":0.03025266,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.5887633,"top":0.6444533,"width":0.0026595744,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":14,"bounds":{"left":0.59142286,"top":0.6444533,"width":0.03706782,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":15,"bounds":{"left":0.59142286,"top":0.6444533,"width":0.03706782,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":14,"bounds":{"left":0.6284907,"top":0.6444533,"width":0.010638298,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":14,"bounds":{"left":0.639129,"top":0.6444533,"width":0.034075797,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":15,"bounds":{"left":0.639129,"top":0.6444533,"width":0.034075797,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"last month","depth":14,"bounds":{"left":0.67453456,"top":0.64285713,"width":0.022606382,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"last month","depth":16,"bounds":{"left":0.67453456,"top":0.6444533,"width":0.022606382,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"bounds":{"left":0.44896942,"top":0.68994415,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"nikolaybiaivanov","depth":15,"bounds":{"left":0.48121676,"top":0.698324,"width":0.036901597,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":16,"bounds":{"left":0.48121676,"top":0.698324,"width":0.036901597,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"approved these changes","depth":14,"bounds":{"left":0.51944816,"top":0.698324,"width":0.05418883,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"on Apr 9","depth":14,"bounds":{"left":0.57363695,"top":0.698324,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"on Apr 9","depth":16,"bounds":{"left":0.57363695,"top":0.698324,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"View reviewed changes","depth":14,"bounds":{"left":0.68517286,"top":0.69393456,"width":0.051030584,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View reviewed changes","depth":16,"bounds":{"left":0.6881649,"top":0.69912213,"width":0.04504654,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":13,"bounds":{"left":0.44896942,"top":0.7418196,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":14,"bounds":{"left":0.72257316,"top":0.7426177,"width":0.007978723,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"yalokin-jiminny commented on Apr 9","depth":13,"bounds":{"left":0.47323802,"top":0.7426177,"width":0.24135639,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":15,"bounds":{"left":0.47323802,"top":0.75059855,"width":0.034075797,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":16,"bounds":{"left":0.47323802,"top":0.75059855,"width":0.034075797,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":14,"bounds":{"left":0.5086436,"top":0.75059855,"width":0.025598405,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"on Apr 9","depth":14,"bounds":{"left":0.5355718,"top":0.7490024,"width":0.018450798,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"on Apr 9","depth":16,"bounds":{"left":0.5355718,"top":0.75059855,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@claude","depth":17,"bounds":{"left":0.47323802,"top":0.7873105,"width":0.019115692,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@claude","depth":18,"bounds":{"left":0.47323802,"top":0.7873105,"width":0.019115692,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":15,"bounds":{"left":0.47323802,"top":0.8152434,"width":0.008643617,"height":0.0207502},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"react with eyes","depth":14,"bounds":{"left":0.48321143,"top":0.8152434,"width":0.013796543,"height":0.0207502},"on_screen":true,"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"👀","depth":16,"bounds":{"left":0.48537233,"top":0.820431,"width":0.004155585,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":16,"bounds":{"left":0.4921875,"top":0.820431,"width":0.0018284575,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@claude","depth":13,"bounds":{"left":0.44896942,"top":0.8750998,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":14,"bounds":{"left":0.72257316,"top":0.8758978,"width":0.007978723,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"claude Bot commented on Apr 9 •","depth":13,"bounds":{"left":0.47323802,"top":0.8758978,"width":0.24135639,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"claude","depth":15,"bounds":{"left":0.47323802,"top":0.8838787,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"claude","depth":16,"bounds":{"left":0.47323802,"top":0.8838787,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bot","depth":16,"bounds":{"left":0.49168882,"top":0.88547486,"width":0.0066489363,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":14,"bounds":{"left":0.50199467,"top":0.8838787,"width":0.02543218,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"on Apr 9","depth":14,"bounds":{"left":0.5287567,"top":0.8822825,"width":0.01861702,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"on Apr 9","depth":16,"bounds":{"left":0.5287567,"top":0.8838787,"width":0.01861702,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":16,"bounds":{"left":0.54870343,"top":0.8838787,"width":0.0019946808,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"edited","depth":16,"bounds":{"left":0.55202794,"top":0.8822825,"width":0.020279255,"height":0.016759777},"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":"edited","depth":18,"bounds":{"left":0.55202794,"top":0.8838787,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude finished","depth":18,"bounds":{"left":0.47323802,"top":0.92098963,"width":0.036070477,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":18,"bounds":{"left":0.5093085,"top":0.92098963,"width":0.038397606,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@yalokin-jiminny","depth":19,"bounds":{"left":0.5093085,"top":0.92098963,"width":0.038397606,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'s task in 1m 11s","depth":18,"bounds":{"left":0.5477061,"top":0.92098963,"width":0.036070477,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"——","depth":17,"bounds":{"left":0.5837766,"top":0.92098963,"width":0.010638298,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"View job","depth":17,"bounds":{"left":0.5944149,"top":0.92098963,"width":0.018284574,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View job","depth":18,"bounds":{"left":0.5944149,"top":0.92098963,"width":0.018284574,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Code Review","depth":16,"bounds":{"left":0.47323802,"top":0.97725457,"width":0.25731382,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code Review","depth":17,"bounds":{"left":0.47323802,"top":0.9776536,"width":0.03523936,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Completed task","depth":18,"bounds":{"left":0.47556517,"top":1.0,"width":0.004654255,"height":-0.011971235},"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Gather context","depth":18,"bounds":{"left":0.48121676,"top":1.0,"width":0.03324468,"height":-0.010774136},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Completed task","depth":18,"bounds":{"left":0.47556517,"top":1.0,"width":0.004654255,"height":-0.031923413},"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Read changed files","depth":18,"bounds":{"left":0.48121676,"top":1.0,"width":0.042220745,"height":-0.030726314},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Completed task","depth":18,"bounds":{"left":0.47556517,"top":1.0,"width":0.004654255,"height":-0.051875472},"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Analyze code and provide review feedback","depth":18,"bounds":{"left":0.48121676,"top":1.0,"width":0.09325133,"height":-0.050678372},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Overall the implementation is clean and well-structured. Good use of the event/listener pattern, proper queuing via","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ShouldQueue","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", and solid test coverage. A few things worth flagging:","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Issues","depth":16,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Issues","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. Silent error swallowing — no logging on","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GuzzleException","depth":19,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Listeners/AutomatedReports/UserPilot/TrackAutomatedReportGeneratedEvent.php","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"L44–45","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"}","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"catch","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(GuzzleException","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"e","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") {","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-6555303186457949091
|
3491512312464879023
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have no unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
JY-20543 add AJ reports User pilot tracking #11932 Edit title
JY-20543 add AJ reports User pilot tracking
#
11932
Edit title
Code
Code
Merged
LakyLak
LakyLak
merged 6 commits into
JY-18909-automated-reports-ask-jiminny
JY-18909-automated-reports-ask-jiminny
from
JY-20543-AJ-report-tracking
JY-20543-AJ-report-tracking
Copy head branch name to clipboard
on Apr 15
Lines changed: 284 additions & 1 deletion
Conversation
Conversation
Commits (6)
Commits
(
6
)
Checks
Checks
Files changed
Files changed
Conversation
Conversation
@LakyLak
Show options
LakyLak commented on Apr 9
LakyLak
LakyLak
commented
on Apr 9
on Apr 9
No description provided.
Add or remove reactions
LakyLak
LakyLak
added
4
commits
last month
last month
@LakyLak
JY-20543
JY-20543
add AJ reports User pilot tracking
add AJ reports User pilot tracking
609200a
609200a
@LakyLak
JY-20543
JY-20543
code smells
code smells
21ab308
21ab308
@LakyLak
JY-20543
JY-20543
fix test
fix test
93a69eb
93a69eb
@LakyLak
JY-20543
JY-20543
fix event
fix event
01241ae
01241ae
@LakyLak
LakyLak
LakyLak
requested review from
Vasil-Jiminny
Vasil-Jiminny
,
nikolaybiaivanov
nikolaybiaivanov
and
yalokin-jiminny
yalokin-jiminny
last month
last month
nikolaybiaivanov
nikolaybiaivanov
nikolaybiaivanov
approved these changes
on Apr 9
on Apr 9
View reviewed changes
View reviewed changes
@yalokin-jiminny
Show options
yalokin-jiminny commented on Apr 9
yalokin-jiminny
yalokin-jiminny
commented
on Apr 9
on Apr 9
@claude
@claude
Add or remove reactions
react with eyes
👀
1
@claude
Show options
claude Bot commented on Apr 9 •
claude
claude
Bot
commented
on Apr 9
on Apr 9
•
edited
edited
Claude finished
@yalokin-jiminny
@yalokin-jiminny
's task in 1m 11s
——
View job
View job
Code Review
Code Review
Completed task
Gather context
Completed task
Read changed files
Completed task
Analyze code and provide review feedback
Overall the implementation is clean and well-structured. Good use of the event/listener pattern, proper queuing via
ShouldQueue
, and solid test coverage. A few things worth flagging:
Issues
Issues
1. Silent error swallowing — no logging on
GuzzleException
app/Listeners/AutomatedReports/UserPilot/TrackAutomatedReportGeneratedEvent.php
L44–45
}
catch
(GuzzleException
$
e
) {
$...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47797
|
1698
|
23
|
2026-05-15T08:53:15.457531+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835195457_m1.jpg...
|
Firefox
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app — Work...
|
1
|
github.com/jiminny/app/pull/11932
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
JY-20543 add AJ reports User pilot tracking #11932 Edit title
JY-20543 add AJ reports User pilot tracking
#
11932
Edit title
Code
Code
Merged
LakyLak
LakyLak
merged 6 commits into
JY-18909-automated-reports-ask-jiminny
JY-18909-automated-reports-ask-jiminny
from
JY-20543-AJ-report-tracking
JY-20543-AJ-report-tracking
Copy head branch name to clipboard
on Apr 15
Lines changed: 284 additions & 1 deletion
Conversation (4)
Conversation
(
4
)
Commits (6)
Commits
(
6
)
Checks (3)
Checks
(
3
)
Files changed (7)
Files changed
(
7
)
Conversation
Conversation
@LakyLak
Show options
LakyLak commented on Apr 9
LakyLak
LakyLak
commented
on Apr 9
on Apr 9
No description provided.
Add or remove reactions
LakyLak
LakyLak
added
4
commits
last month
last month
@LakyLak
JY-20543
JY-20543
add AJ reports User pilot tracking
add AJ reports User pilot tracking
2 / 4 checks OK
609200a
609200a
@LakyLak
JY-20543
JY-20543
code smells
code smells
8 / 10 checks OK
21ab308
21ab308
@LakyLak
JY-20543
JY-20543
fix test
fix test
21 / 21 checks OK
93a69eb
93a69eb
@LakyLak
JY-20543...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"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,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"JY-20543 add AJ reports User pilot tracking #11932 Edit title","depth":13,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11932","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit title","depth":14,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Code","depth":13,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Code","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merged","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":15,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"merged 6 commits into","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-18909-automated-reports-ask-jiminny","depth":15,"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-18909-automated-reports-ask-jiminny","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20543-AJ-report-tracking","depth":16,"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543-AJ-report-tracking","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"on Apr 15","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lines changed: 284 additions & 1 deletion","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Conversation (4)","depth":16,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Conversation","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Commits (6)","depth":16,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Commits","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Checks (3)","depth":16,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Checks","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Files changed (7)","depth":16,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Files changed","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Conversation","depth":12,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":15,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"LakyLak commented on Apr 9","depth":14,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"on Apr 9","depth":15,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"on Apr 9","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No description provided.","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":16,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"added","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commits","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"last month","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"last month","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"add AJ reports User pilot tracking","depth":14,"on_screen":true,"help_text":"JY-20543 add AJ reports User pilot tracking","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"add AJ reports User pilot tracking","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"2 / 4 checks OK","depth":14,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"609200a","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"609200a","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"code smells","depth":14,"on_screen":true,"help_text":"JY-20543 code smells","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"code smells","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":14,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"21ab308","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"21ab308","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"fix test","depth":14,"on_screen":true,"help_text":"JY-20543 fix test","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix test","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 21 checks OK","depth":14,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"93a69eb","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"93a69eb","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
7057885243199404355
|
-5591966669621949044
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
JY-20543 add AJ reports User pilot tracking #11932 Edit title
JY-20543 add AJ reports User pilot tracking
#
11932
Edit title
Code
Code
Merged
LakyLak
LakyLak
merged 6 commits into
JY-18909-automated-reports-ask-jiminny
JY-18909-automated-reports-ask-jiminny
from
JY-20543-AJ-report-tracking
JY-20543-AJ-report-tracking
Copy head branch name to clipboard
on Apr 15
Lines changed: 284 additions & 1 deletion
Conversation (4)
Conversation
(
4
)
Commits (6)
Commits
(
6
)
Checks (3)
Checks
(
3
)
Files changed (7)
Files changed
(
7
)
Conversation
Conversation
@LakyLak
Show options
LakyLak commented on Apr 9
LakyLak
LakyLak
commented
on Apr 9
on Apr 9
No description provided.
Add or remove reactions
LakyLak
LakyLak
added
4
commits
last month
last month
@LakyLak
JY-20543
JY-20543
add AJ reports User pilot tracking
add AJ reports User pilot tracking
2 / 4 checks OK
609200a
609200a
@LakyLak
JY-20543
JY-20543
code smells
code smells
8 / 10 checks OK
21ab308
21ab308
@LakyLak
JY-20543
JY-20543
fix test
fix test
21 / 21 checks OK
93a69eb
93a69eb
@LakyLak
JY-20543...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47798
|
1699
|
34
|
2026-05-15T08:53:15.457546+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835195457_m2.jpg...
|
Firefox
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app — Work...
|
1
|
github.com/jiminny/app/pull/11932
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
JY-20543 add AJ reports User pilot tracking #11932 Edit title
JY-20543 add AJ reports User pilot tracking
#
11932
Edit title
Code
Code
Merged
LakyLak
LakyLak
merged 6 commits into
JY-18909-automated-reports-ask-jiminny
JY-18909-automated-reports-ask-jiminny
from
JY-20543-AJ-report-tracking
JY-20543-AJ-report-tracking
Copy head branch name to clipboard
on Apr 15
Lines changed: 284 additions & 1 deletion
Conversation (4)
Conversation
(
4
)
Commits (6)
Commits
(
6
)
Checks (3)
Checks
(
3
)
Files changed (7)
Files changed
(
7
)
Conversation
Conversation
@LakyLak
Show options
LakyLak commented on Apr 9
LakyLak
LakyLak
commented
on Apr 9
on Apr 9
No description provided.
Add or remove reactions
LakyLak
LakyLak
added
4
commits
last month
last month
@LakyLak
JY-20543
JY-20543
add AJ reports User pilot tracking
add AJ reports User pilot tracking
2 / 4 checks OK
609200a
609200a
@LakyLak
JY-20543
JY-20543
code smells
code smells
8 / 10 checks OK
21ab308
21ab308
@LakyLak
JY-20543
JY-20543
fix test
fix test
21 / 21 checks OK
93a69eb
93a69eb
@LakyLak
JY-20543
JY-20543
fix event
fix event
21 / 22 checks OK
01241ae
01241ae
@LakyLak
LakyLak
LakyLak
requested review from
Vasil-Jiminny
Vasil-Jiminny
,
nikolaybiaivanov
nikolaybiaivanov
and
yalokin-jiminny
yalokin-jiminny
last month
last month
nikolaybiaivanov
nikolaybiaivanov
nikolaybiaivanov
approved these changes
on Apr 9
on Apr 9
View reviewed changes
View reviewed changes
@yalokin-jiminny...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.15924202,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.38627294,"width":0.007978723,"height":0.01915403},"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.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.3020279,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.3020279,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.3073471,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.32197472,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.3352726,"top":0.06464485,"width":0.018949468,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.33726728,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.35920876,"top":0.06464485,"width":0.017785905,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.36120346,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.30169547,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.30169547,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.3073471,"top":0.09936153,"width":0.025099734,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.3181516,"top":0.10574621,"width":0.011469414,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"bounds":{"left":0.33510637,"top":0.09936153,"width":0.05518617,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.34574467,"top":0.10574621,"width":0.02925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.3776596,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"bounds":{"left":0.3806516,"top":0.113727055,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.38646942,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.3929521,"top":0.09936153,"width":0.029089095,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.4039229,"top":0.10574621,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.4247008,"top":0.09936153,"width":0.03025266,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.43583778,"top":0.10574621,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.45761302,"top":0.09936153,"width":0.022938829,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.46841756,"top":0.10574621,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"bounds":{"left":0.48321143,"top":0.09936153,"width":0.05817819,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.4950133,"top":0.10574621,"width":0.04255319,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.5440492,"top":0.09936153,"width":0.03125,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.55518615,"top":0.10574621,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.57795876,"top":0.09936153,"width":0.032081116,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.5890958,"top":0.10574621,"width":0.01761968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.31565824,"top":0.14365523,"width":0.0003324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.039228722,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.2159242,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.57214093,"top":0.1452514,"width":0.08261303,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.70694816,"top":0.1452514,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.13886672,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"JY-20543 add AJ reports User pilot tracking #11932 Edit title","depth":13,"bounds":{"left":0.44896942,"top":0.19193934,"width":0.25116357,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking","depth":14,"bounds":{"left":0.44896942,"top":0.19273743,"width":0.20162898,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":15,"bounds":{"left":0.65325797,"top":0.19273743,"width":0.006482713,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11932","depth":15,"bounds":{"left":0.6597407,"top":0.19273743,"width":0.028424202,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit title","depth":14,"bounds":{"left":0.68949467,"top":0.19513169,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Code","depth":13,"bounds":{"left":0.8249667,"top":0.19832402,"width":0.02825798,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Code","depth":15,"bounds":{"left":0.82928854,"top":0.20430966,"width":0.011635638,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merged","depth":13,"bounds":{"left":0.45960772,"top":0.23623304,"width":0.017121011,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":15,"bounds":{"left":0.48337767,"top":0.2330407,"width":0.01861702,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":16,"bounds":{"left":0.48337767,"top":0.23463687,"width":0.01861702,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"merged 6 commits into","depth":15,"bounds":{"left":0.50332445,"top":0.23463687,"width":0.049700797,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-18909-automated-reports-ask-jiminny","depth":15,"bounds":{"left":0.554355,"top":0.23264167,"width":0.09507979,"height":0.017557861},"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-18909-automated-reports-ask-jiminny","depth":16,"bounds":{"left":0.55634975,"top":0.235834,"width":0.091090426,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":16,"bounds":{"left":0.65076464,"top":0.23463687,"width":0.009973404,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20543-AJ-report-tracking","depth":16,"bounds":{"left":0.66206783,"top":0.23264167,"width":0.06881649,"height":0.017557861},"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543-AJ-report-tracking","depth":17,"bounds":{"left":0.6640625,"top":0.235834,"width":0.06482713,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":16,"bounds":{"left":0.7322141,"top":0.23024741,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"on Apr 15","depth":16,"bounds":{"left":0.7428524,"top":0.23463687,"width":0.02044548,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lines changed: 284 additions & 1 deletion","depth":14,"bounds":{"left":0.8211436,"top":0.28651237,"width":0.019946808,"height":0.11412609},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Conversation (4)","depth":16,"bounds":{"left":0.44896942,"top":0.26855546,"width":0.054853722,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Conversation","depth":17,"bounds":{"left":0.46126994,"top":0.27813247,"width":0.028091755,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.49950132,"top":0.27813247,"width":0.0028257978,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":18,"bounds":{"left":0.50232714,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.5053192,"top":0.27813247,"width":0.0018284575,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Commits (6)","depth":16,"bounds":{"left":0.50382316,"top":0.26855546,"width":0.045545213,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Commits","depth":17,"bounds":{"left":0.51612365,"top":0.27813247,"width":0.018949468,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.54504657,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6","depth":18,"bounds":{"left":0.54803854,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.5510306,"top":0.27813247,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Checks (3)","depth":16,"bounds":{"left":0.5493683,"top":0.26855546,"width":0.04255319,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Checks","depth":17,"bounds":{"left":0.5616689,"top":0.27813247,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.58759975,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3","depth":18,"bounds":{"left":0.5905917,"top":0.27813247,"width":0.0028257978,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.5934175,"top":0.27813247,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Files changed (7)","depth":16,"bounds":{"left":0.59192157,"top":0.26855546,"width":0.056017287,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Files changed","depth":17,"bounds":{"left":0.60422206,"top":0.27813247,"width":0.029753989,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.64361703,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7","depth":18,"bounds":{"left":0.64660907,"top":0.27813247,"width":0.0026595744,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.6492686,"top":0.27813247,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Conversation","depth":12,"bounds":{"left":0.44896942,"top":0.3140463,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation","depth":13,"bounds":{"left":0.44896942,"top":0.31683958,"width":0.048204787,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.44896942,"top":0.3140463,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":15,"bounds":{"left":0.72257316,"top":0.31484437,"width":0.007978723,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"LakyLak commented on Apr 9","depth":14,"bounds":{"left":0.47323802,"top":0.31484437,"width":0.24135639,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":16,"bounds":{"left":0.47323802,"top":0.32282522,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":17,"bounds":{"left":0.47323802,"top":0.32282522,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":15,"bounds":{"left":0.49301863,"top":0.32282522,"width":0.025598405,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"on Apr 9","depth":15,"bounds":{"left":0.5199468,"top":0.32122904,"width":0.018450798,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"on Apr 9","depth":17,"bounds":{"left":0.5199468,"top":0.32282522,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No description provided.","depth":18,"bounds":{"left":0.47323802,"top":0.35953712,"width":0.05285904,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":16,"bounds":{"left":0.47323802,"top":0.38747007,"width":0.008643617,"height":0.0207502},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"LakyLak","depth":14,"bounds":{"left":0.48121676,"top":0.45291302,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":15,"bounds":{"left":0.48121676,"top":0.45291302,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"added","depth":14,"bounds":{"left":0.49966756,"top":0.45291302,"width":0.016289894,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":14,"bounds":{"left":0.5159575,"top":0.45291302,"width":0.0028257978,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commits","depth":14,"bounds":{"left":0.5187833,"top":0.45291302,"width":0.020944148,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"last month","depth":14,"bounds":{"left":0.5397274,"top":0.45291302,"width":0.022772606,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"last month","depth":16,"bounds":{"left":0.5397274,"top":0.45291302,"width":0.022772606,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.48121676,"top":0.49281725,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"bounds":{"left":0.4898604,"top":0.4964086,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543","depth":15,"bounds":{"left":0.4898604,"top":0.4964086,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"add AJ reports User pilot tracking","depth":14,"bounds":{"left":0.5113032,"top":0.4964086,"width":0.081615694,"height":0.011572227},"on_screen":true,"help_text":"JY-20543 add AJ reports User pilot tracking","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"add AJ reports User pilot tracking","depth":15,"bounds":{"left":0.5113032,"top":0.4964086,"width":0.081615694,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"2 / 4 checks OK","depth":14,"bounds":{"left":0.71259975,"top":0.49281725,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"609200a","depth":14,"bounds":{"left":0.71924865,"top":0.4964086,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"609200a","depth":15,"bounds":{"left":0.71924865,"top":0.4964086,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.48121676,"top":0.5343176,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"bounds":{"left":0.4898604,"top":0.53790903,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543","depth":15,"bounds":{"left":0.4898604,"top":0.53790903,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"code smells","depth":14,"bounds":{"left":0.5113032,"top":0.53790903,"width":0.02642952,"height":0.011572227},"on_screen":true,"help_text":"JY-20543 code smells","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"code smells","depth":15,"bounds":{"left":0.5113032,"top":0.53790903,"width":0.02642952,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":14,"bounds":{"left":0.71259975,"top":0.5343176,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"21ab308","depth":14,"bounds":{"left":0.71924865,"top":0.53790903,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"21ab308","depth":15,"bounds":{"left":0.71924865,"top":0.53790903,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.48121676,"top":0.56304866,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"bounds":{"left":0.4898604,"top":0.5666401,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543","depth":15,"bounds":{"left":0.4898604,"top":0.5666401,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"fix test","depth":14,"bounds":{"left":0.5113032,"top":0.5666401,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"JY-20543 fix test","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix test","depth":15,"bounds":{"left":0.5113032,"top":0.5666401,"width":0.019281914,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 21 checks OK","depth":14,"bounds":{"left":0.71259975,"top":0.56304866,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"93a69eb","depth":14,"bounds":{"left":0.71924865,"top":0.5666401,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"93a69eb","depth":15,"bounds":{"left":0.71924865,"top":0.5666401,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.48121676,"top":0.5917797,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20543","depth":14,"bounds":{"left":0.4898604,"top":0.5953711,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543","depth":15,"bounds":{"left":0.4898604,"top":0.5953711,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"fix event","depth":14,"bounds":{"left":0.5113032,"top":0.5953711,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"JY-20543 fix event","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix event","depth":15,"bounds":{"left":0.5113032,"top":0.5953711,"width":0.021609042,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 22 checks OK","depth":14,"bounds":{"left":0.71259975,"top":0.5917797,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"01241ae","depth":14,"bounds":{"left":0.71924865,"top":0.5953711,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"01241ae","depth":15,"bounds":{"left":0.71924865,"top":0.5953711,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":14,"bounds":{"left":0.48121676,"top":0.64285713,"width":0.0066489363,"height":0.017956903},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"LakyLak","depth":14,"bounds":{"left":0.48902926,"top":0.6444533,"width":0.01861702,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":15,"bounds":{"left":0.48902926,"top":0.6444533,"width":0.01861702,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"requested review from","depth":14,"bounds":{"left":0.50764626,"top":0.6444533,"width":0.05086436,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":14,"bounds":{"left":0.55851066,"top":0.6444533,"width":0.03025266,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":15,"bounds":{"left":0.55851066,"top":0.6444533,"width":0.03025266,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.5887633,"top":0.6444533,"width":0.0026595744,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":14,"bounds":{"left":0.59142286,"top":0.6444533,"width":0.03706782,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":15,"bounds":{"left":0.59142286,"top":0.6444533,"width":0.03706782,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":14,"bounds":{"left":0.6284907,"top":0.6444533,"width":0.010638298,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":14,"bounds":{"left":0.639129,"top":0.6444533,"width":0.034075797,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":15,"bounds":{"left":0.639129,"top":0.6444533,"width":0.034075797,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"last month","depth":14,"bounds":{"left":0.67453456,"top":0.64285713,"width":0.022606382,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"last month","depth":16,"bounds":{"left":0.67453456,"top":0.6444533,"width":0.022606382,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"bounds":{"left":0.44896942,"top":0.68994415,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"nikolaybiaivanov","depth":15,"bounds":{"left":0.48121676,"top":0.698324,"width":0.036901597,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":16,"bounds":{"left":0.48121676,"top":0.698324,"width":0.036901597,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"approved these changes","depth":14,"bounds":{"left":0.51944816,"top":0.698324,"width":0.05418883,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"on Apr 9","depth":14,"bounds":{"left":0.57363695,"top":0.698324,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"on Apr 9","depth":16,"bounds":{"left":0.57363695,"top":0.698324,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"View reviewed changes","depth":14,"bounds":{"left":0.68517286,"top":0.69393456,"width":0.051030584,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View reviewed changes","depth":16,"bounds":{"left":0.6881649,"top":0.69912213,"width":0.04504654,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":13,"bounds":{"left":0.44896942,"top":0.7418196,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
4677470049994557392
|
3613320599979167117
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
JY-20543 add AJ reports User pilot tracking #11932 Edit title
JY-20543 add AJ reports User pilot tracking
#
11932
Edit title
Code
Code
Merged
LakyLak
LakyLak
merged 6 commits into
JY-18909-automated-reports-ask-jiminny
JY-18909-automated-reports-ask-jiminny
from
JY-20543-AJ-report-tracking
JY-20543-AJ-report-tracking
Copy head branch name to clipboard
on Apr 15
Lines changed: 284 additions & 1 deletion
Conversation (4)
Conversation
(
4
)
Commits (6)
Commits
(
6
)
Checks (3)
Checks
(
3
)
Files changed (7)
Files changed
(
7
)
Conversation
Conversation
@LakyLak
Show options
LakyLak commented on Apr 9
LakyLak
LakyLak
commented
on Apr 9
on Apr 9
No description provided.
Add or remove reactions
LakyLak
LakyLak
added
4
commits
last month
last month
@LakyLak
JY-20543
JY-20543
add AJ reports User pilot tracking
add AJ reports User pilot tracking
2 / 4 checks OK
609200a
609200a
@LakyLak
JY-20543
JY-20543
code smells
code smells
8 / 10 checks OK
21ab308
21ab308
@LakyLak
JY-20543
JY-20543
fix test
fix test
21 / 21 checks OK
93a69eb
93a69eb
@LakyLak
JY-20543
JY-20543
fix event
fix event
21 / 22 checks OK
01241ae
01241ae
@LakyLak
LakyLak
LakyLak
requested review from
Vasil-Jiminny
Vasil-Jiminny
,
nikolaybiaivanov
nikolaybiaivanov
and
yalokin-jiminny
yalokin-jiminny
last month
last month
nikolaybiaivanov
nikolaybiaivanov
nikolaybiaivanov
approved these changes
on Apr 9
on Apr 9
View reviewed changes
View reviewed changes
@yalokin-jiminny...
|
47796
|
NULL
|
NULL
|
NULL
|
|
47800
|
1699
|
35
|
2026-05-15T08:53:18.861495+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835198861_m2.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
30 Open
30 Open
10,998 Closed
10,998 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
9 / 11 checks OK
#12085 opened
15 minutes ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
21 / 22 checks OK
#12084 opened
1 hour ago
by
ilian-jiminny...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.38627294,"width":0.007978723,"height":0.01915403},"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.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.3020279,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.3020279,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.3073471,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.32197472,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.3352726,"top":0.06464485,"width":0.018949468,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.33726728,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.35920876,"top":0.06464485,"width":0.017785905,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.36120346,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.30169547,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.30169547,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.3073471,"top":0.09936153,"width":0.025099734,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.3181516,"top":0.10574621,"width":0.011469414,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"bounds":{"left":0.33510637,"top":0.09936153,"width":0.05518617,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.34574467,"top":0.10574621,"width":0.02925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.3776596,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"bounds":{"left":0.3806516,"top":0.113727055,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.38646942,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.3929521,"top":0.09936153,"width":0.029089095,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.4039229,"top":0.10574621,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.4247008,"top":0.09936153,"width":0.03025266,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.43583778,"top":0.10574621,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.45761302,"top":0.09936153,"width":0.022938829,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.46841756,"top":0.10574621,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"bounds":{"left":0.48321143,"top":0.09936153,"width":0.05817819,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.4950133,"top":0.10574621,"width":0.04255319,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.5440492,"top":0.09936153,"width":0.03125,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.55518615,"top":0.10574621,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.57795876,"top":0.09936153,"width":0.032081116,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.5890958,"top":0.10574621,"width":0.01761968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.31565824,"top":0.14365523,"width":0.0003324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.039228722,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.2159242,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.57214093,"top":0.1452514,"width":0.08261303,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.70694816,"top":0.1452514,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.13886672,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"bounds":{"left":0.44896942,"top":0.19553073,"width":0.04488032,"height":0.1452514},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.027426861,"height":0.025538707},"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":"Filters","depth":13,"bounds":{"left":0.45329124,"top":0.19752593,"width":0.013464096,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:pr is:open","depth":11,"bounds":{"left":0.47606382,"top":0.1915403,"width":0.23105054,"height":0.025538707},"on_screen":true,"value":"is:pr is:open","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"bounds":{"left":0.7124335,"top":0.1915403,"width":0.043218084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"bounds":{"left":0.7234042,"top":0.19752593,"width":0.016954787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"bounds":{"left":0.74268615,"top":0.1991221,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"bounds":{"left":0.7553192,"top":0.1915403,"width":0.049534574,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"bounds":{"left":0.7662899,"top":0.19752593,"width":0.026263298,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.79488033,"top":0.1991221,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"bounds":{"left":0.8075133,"top":0.1915403,"width":0.045711435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"bounds":{"left":0.8118351,"top":0.19752593,"width":0.03706782,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"bounds":{"left":0.45462102,"top":0.24581006,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"30 Open","depth":11,"bounds":{"left":0.46459442,"top":0.2434158,"width":0.027094414,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"30 Open","depth":12,"bounds":{"left":0.47124335,"top":0.24501197,"width":0.02044548,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"10,998 Closed","depth":11,"bounds":{"left":0.49634308,"top":0.2434158,"width":0.038896278,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10,998 Closed","depth":12,"bounds":{"left":0.50299203,"top":0.24501197,"width":0.032247342,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"bounds":{"left":0.64045876,"top":0.2434158,"width":0.018284574,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Author","depth":12,"bounds":{"left":0.64045876,"top":0.24501197,"width":0.015625,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"bounds":{"left":0.6693817,"top":0.2434158,"width":0.015625,"height":0.016759777},"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":"Label","depth":12,"bounds":{"left":0.6693817,"top":0.24501197,"width":0.012965426,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"bounds":{"left":0.695645,"top":0.2434158,"width":0.02144282,"height":0.016759777},"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":"Projects","depth":13,"bounds":{"left":0.695645,"top":0.24501197,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","depth":12,"bounds":{"left":0.7290558,"top":0.2434158,"width":0.027260639,"height":0.016759777},"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":"Milestones","depth":13,"bounds":{"left":0.7290558,"top":0.24501197,"width":0.024601065,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","depth":12,"bounds":{"left":0.76828456,"top":0.2434158,"width":0.02144282,"height":0.016759777},"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":"Reviews","depth":13,"bounds":{"left":0.76828456,"top":0.24501197,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"bounds":{"left":0.8003657,"top":0.2434158,"width":0.0234375,"height":0.016759777},"on_screen":true,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"bounds":{"left":0.8003657,"top":0.24501197,"width":0.020777926,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"bounds":{"left":0.8344415,"top":0.2434158,"width":0.013131649,"height":0.016759777},"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":"Sort","depth":12,"bounds":{"left":0.8344415,"top":0.24501197,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"bounds":{"left":0.44930187,"top":0.273743,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"bounds":{"left":0.44930187,"top":0.27653632,"width":0.03174867,"height":0.08060654},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20671 Fix S3 For Twilio","depth":12,"bounds":{"left":0.45462102,"top":0.28332004,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20671 Fix S3 For Twilio","depth":12,"bounds":{"left":0.47257313,"top":0.28332004,"width":0.066821806,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20671 Fix S3 For Twilio","depth":13,"bounds":{"left":0.47257313,"top":0.28332004,"width":0.066821806,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"9 / 11 checks OK","depth":13,"bounds":{"left":0.54072475,"top":0.28092578,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12085 opened","depth":13,"bounds":{"left":0.47257313,"top":0.3048683,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15 minutes ago","depth":14,"bounds":{"left":0.5031583,"top":0.3048683,"width":0.028424202,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.5315825,"top":0.3048683,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny","depth":13,"bounds":{"left":0.5383976,"top":0.3048683,"width":0.022606382,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by ilian-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ilian-jiminny","depth":14,"bounds":{"left":0.5383976,"top":0.3048683,"width":0.022606382,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.56233376,"top":0.3048683,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.5653258,"top":0.3048683,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.5653258,"top":0.3048683,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny’s assigned issues","depth":13,"bounds":{"left":0.8090093,"top":0.28411812,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"introduce-new-kiosk-login-features","depth":12,"bounds":{"left":0.45462102,"top":0.3339984,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"introduce-new-kiosk-login-features","depth":12,"bounds":{"left":0.47257313,"top":0.33359936,"width":0.09042553,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"introduce-new-kiosk-login-features","depth":13,"bounds":{"left":0.47257313,"top":0.33359936,"width":0.09042553,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 22 checks OK","depth":13,"bounds":{"left":0.56432843,"top":0.33160415,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12084 opened","depth":13,"bounds":{"left":0.47257313,"top":0.35514766,"width":0.030751329,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 hour ago","depth":14,"bounds":{"left":0.50332445,"top":0.35514766,"width":0.019614361,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.52293885,"top":0.35514766,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny","depth":13,"bounds":{"left":0.529754,"top":0.35514766,"width":0.02244016,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by ilian-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
7256953349556565918
|
-5898381030522479570
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
30 Open
30 Open
10,998 Closed
10,998 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
9 / 11 checks OK
#12085 opened
15 minutes ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
21 / 22 checks OK
#12084 opened
1 hour ago
by
ilian-jiminny...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47799
|
1698
|
24
|
2026-05-15T08:53:18.861528+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835198861_m1.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
30 Open
30 Open
10,998 Closed
10,998 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
9 / 11 checks OK
#12085 opened
15 minutes ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
21 / 22 checks OK
#12084 opened
1 hour ago
by...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"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,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"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":"Filters","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:pr is:open","depth":11,"on_screen":true,"value":"is:pr is:open","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"30 Open","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"30 Open","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"10,998 Closed","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10,998 Closed","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Author","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"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":"Label","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","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":"Projects","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","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":"Milestones","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","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":"Reviews","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"on_screen":true,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"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":"Sort","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20671 Fix S3 For Twilio","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20671 Fix S3 For Twilio","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20671 Fix S3 For Twilio","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"9 / 11 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12085 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15 minutes ago","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny","depth":13,"on_screen":true,"help_text":"Open pull requests created by ilian-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ilian-jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny’s assigned issues","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"introduce-new-kiosk-login-features","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"introduce-new-kiosk-login-features","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"introduce-new-kiosk-login-features","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 22 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12084 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 hour ago","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
3313398822379652614
|
-5898381030522479570
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
30 Open
30 Open
10,998 Closed
10,998 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
9 / 11 checks OK
#12085 opened
15 minutes ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
21 / 22 checks OK
#12084 opened
1 hour ago
by...
|
47797
|
NULL
|
NULL
|
NULL
|
|
47801
|
1698
|
25
|
2026-05-15T08:53:19.887629+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835199887_m1.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
30 Open
30 Open
10,998 Closed
10,998 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
9 / 11 checks OK
#12085 opened
15 minutes ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
21 / 22 checks OK
#12084 opened
1 hour ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
1 comment
1
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
12 / 12 checks OK
#12083 opened
17 hours ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20808 low priority indexing queue
JY-20808 low priority indexing queue
JY-20808 low priority indexing queue
8 / 10 checks OK
#12082 opened
17 hours ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
JY-20900: fix calendar event deletion
JY-20900: fix calendar event deletion
JY-20900: fix calendar event deletion
12 / 13 checks OK
#12079 opened
20 hours ago
by
TodorStamatovJiminny
TodorStamatovJiminny
•
1 review approval
Approved...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"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,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"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":"Filters","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:pr is:open","depth":11,"on_screen":true,"value":"is:pr is:open","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"30 Open","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"30 Open","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"10,998 Closed","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10,998 Closed","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Author","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"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":"Label","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","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":"Projects","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","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":"Milestones","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","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":"Reviews","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"on_screen":true,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"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":"Sort","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20671 Fix S3 For Twilio","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20671 Fix S3 For Twilio","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20671 Fix S3 For Twilio","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"9 / 11 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12085 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15 minutes ago","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny","depth":13,"on_screen":true,"help_text":"Open pull requests created by ilian-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ilian-jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny’s assigned issues","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"introduce-new-kiosk-login-features","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"introduce-new-kiosk-login-features","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"introduce-new-kiosk-login-features","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 22 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12084 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 hour ago","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny","depth":13,"on_screen":true,"help_text":"Open pull requests created by ilian-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ilian-jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny’s assigned issues","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"1 comment","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12083 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17 hours ago","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"mihailmihaylovjiminny","depth":13,"on_screen":true,"help_text":"Open pull requests created by mihailmihaylovjiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20808 low priority indexing queue","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20808 low priority indexing queue","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12082 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17 hours ago","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"on_screen":true,"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20900: fix calendar event deletion","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20900: fix calendar event deletion","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20900: fix calendar event deletion","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12079 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20 hours ago","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"TodorStamatovJiminny","depth":13,"on_screen":true,"help_text":"Open pull requests created by TodorStamatovJiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"TodorStamatovJiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-3648352072582261732
|
-1385721414420848764
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
30 Open
30 Open
10,998 Closed
10,998 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
9 / 11 checks OK
#12085 opened
15 minutes ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
21 / 22 checks OK
#12084 opened
1 hour ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
1 comment
1
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
12 / 12 checks OK
#12083 opened
17 hours ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20808 low priority indexing queue
JY-20808 low priority indexing queue
JY-20808 low priority indexing queue
8 / 10 checks OK
#12082 opened
17 hours ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
JY-20900: fix calendar event deletion
JY-20900: fix calendar event deletion
JY-20900: fix calendar event deletion
12 / 13 checks OK
#12079 opened
20 hours ago
by
TodorStamatovJiminny
TodorStamatovJiminny
•
1 review approval
Approved...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47802
|
1699
|
36
|
2026-05-15T08:53:19.908725+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835199908_m2.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
30 Open
30 Open
10,998 Closed
10,998 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
9 / 11 checks OK
#12085 opened
15 minutes ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
21 / 22 checks OK
#12084 opened
1 hour ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
1 comment
1
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
12 / 12 checks OK
#12083 opened
17 hours ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20808 low priority indexing queue
JY-20808 low priority indexing queue
JY-20808 low priority indexing queue
8 / 10 checks OK
#12082 opened
17 hours ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
JY-20900: fix calendar event deletion
JY-20900: fix calendar event deletion
JY-20900: fix calendar event deletion
12 / 13 checks OK
#12079 opened
20 hours ago
by
TodorStamatovJiminny
TodorStamatovJiminny
•
1 review approval
Approved
1 comment
1
WIP: JY-20853 | JY-20833 add paginated results, fix ES query, skip first result per…
WIP: JY-20853 | JY-20833 add paginated results, fix ES query, skip first result per…
WIP: JY-20853 | JY-20833 add paginated results, fix ES query, skip first result per…
12 / 12 checks OK
#12076 opened
yesterday
by
yalokin-jiminny
yalokin-jiminny
•
Draft
Draft
3 comments
3
Jy 20846 mcp enable the ai to know details about the user
Jy 20846 mcp enable the ai to know details about the user
Jy 20846 mcp enable the ai to know details about the user
8 / 10 checks OK
#12075 opened
2 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.38627294,"width":0.007978723,"height":0.01915403},"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.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.3020279,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.3020279,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.3073471,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.32197472,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.3352726,"top":0.06464485,"width":0.018949468,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.33726728,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.35920876,"top":0.06464485,"width":0.017785905,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.36120346,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.30169547,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.30169547,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.3073471,"top":0.09936153,"width":0.025099734,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.3181516,"top":0.10574621,"width":0.011469414,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"bounds":{"left":0.33510637,"top":0.09936153,"width":0.05518617,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.34574467,"top":0.10574621,"width":0.02925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.3776596,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"bounds":{"left":0.3806516,"top":0.113727055,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.38646942,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.3929521,"top":0.09936153,"width":0.029089095,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.4039229,"top":0.10574621,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.4247008,"top":0.09936153,"width":0.03025266,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.43583778,"top":0.10574621,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.45761302,"top":0.09936153,"width":0.022938829,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.46841756,"top":0.10574621,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"bounds":{"left":0.48321143,"top":0.09936153,"width":0.05817819,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.4950133,"top":0.10574621,"width":0.04255319,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.5440492,"top":0.09936153,"width":0.03125,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.55518615,"top":0.10574621,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.57795876,"top":0.09936153,"width":0.032081116,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.5890958,"top":0.10574621,"width":0.01761968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.31565824,"top":0.14365523,"width":0.0003324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.039228722,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.2159242,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.57214093,"top":0.1452514,"width":0.08261303,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.70694816,"top":0.1452514,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.13886672,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"bounds":{"left":0.44896942,"top":0.19553073,"width":0.04488032,"height":0.1452514},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.027426861,"height":0.025538707},"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":"Filters","depth":13,"bounds":{"left":0.45329124,"top":0.19752593,"width":0.013464096,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:pr is:open","depth":11,"bounds":{"left":0.47606382,"top":0.1915403,"width":0.23105054,"height":0.025538707},"on_screen":true,"value":"is:pr is:open","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"bounds":{"left":0.7124335,"top":0.1915403,"width":0.043218084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"bounds":{"left":0.7234042,"top":0.19752593,"width":0.016954787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"bounds":{"left":0.74268615,"top":0.1991221,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"bounds":{"left":0.7553192,"top":0.1915403,"width":0.049534574,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"bounds":{"left":0.7662899,"top":0.19752593,"width":0.026263298,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.79488033,"top":0.1991221,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"bounds":{"left":0.8075133,"top":0.1915403,"width":0.045711435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"bounds":{"left":0.8118351,"top":0.19752593,"width":0.03706782,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"bounds":{"left":0.45462102,"top":0.24581006,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"30 Open","depth":11,"bounds":{"left":0.46459442,"top":0.2434158,"width":0.027094414,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"30 Open","depth":12,"bounds":{"left":0.47124335,"top":0.24501197,"width":0.02044548,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"10,998 Closed","depth":11,"bounds":{"left":0.49634308,"top":0.2434158,"width":0.038896278,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10,998 Closed","depth":12,"bounds":{"left":0.50299203,"top":0.24501197,"width":0.032247342,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"bounds":{"left":0.64045876,"top":0.2434158,"width":0.018284574,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Author","depth":12,"bounds":{"left":0.64045876,"top":0.24501197,"width":0.015625,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"bounds":{"left":0.6693817,"top":0.2434158,"width":0.015625,"height":0.016759777},"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":"Label","depth":12,"bounds":{"left":0.6693817,"top":0.24501197,"width":0.012965426,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"bounds":{"left":0.695645,"top":0.2434158,"width":0.02144282,"height":0.016759777},"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":"Projects","depth":13,"bounds":{"left":0.695645,"top":0.24501197,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","depth":12,"bounds":{"left":0.7290558,"top":0.2434158,"width":0.027260639,"height":0.016759777},"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":"Milestones","depth":13,"bounds":{"left":0.7290558,"top":0.24501197,"width":0.024601065,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","depth":12,"bounds":{"left":0.76828456,"top":0.2434158,"width":0.02144282,"height":0.016759777},"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":"Reviews","depth":13,"bounds":{"left":0.76828456,"top":0.24501197,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"bounds":{"left":0.8003657,"top":0.2434158,"width":0.0234375,"height":0.016759777},"on_screen":true,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"bounds":{"left":0.8003657,"top":0.24501197,"width":0.020777926,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"bounds":{"left":0.8344415,"top":0.2434158,"width":0.013131649,"height":0.016759777},"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":"Sort","depth":12,"bounds":{"left":0.8344415,"top":0.24501197,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"bounds":{"left":0.44930187,"top":0.273743,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"bounds":{"left":0.44930187,"top":0.27653632,"width":0.03174867,"height":0.08060654},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20671 Fix S3 For Twilio","depth":12,"bounds":{"left":0.45462102,"top":0.28332004,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20671 Fix S3 For Twilio","depth":12,"bounds":{"left":0.47257313,"top":0.28332004,"width":0.066821806,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20671 Fix S3 For Twilio","depth":13,"bounds":{"left":0.47257313,"top":0.28332004,"width":0.066821806,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"9 / 11 checks OK","depth":13,"bounds":{"left":0.54072475,"top":0.28092578,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12085 opened","depth":13,"bounds":{"left":0.47257313,"top":0.3048683,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15 minutes ago","depth":14,"bounds":{"left":0.5031583,"top":0.3048683,"width":0.028424202,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.5315825,"top":0.3048683,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny","depth":13,"bounds":{"left":0.5383976,"top":0.3048683,"width":0.022606382,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by ilian-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ilian-jiminny","depth":14,"bounds":{"left":0.5383976,"top":0.3048683,"width":0.022606382,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.56233376,"top":0.3048683,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.5653258,"top":0.3048683,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.5653258,"top":0.3048683,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny’s assigned issues","depth":13,"bounds":{"left":0.8090093,"top":0.28411812,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"introduce-new-kiosk-login-features","depth":12,"bounds":{"left":0.45462102,"top":0.3339984,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"introduce-new-kiosk-login-features","depth":12,"bounds":{"left":0.47257313,"top":0.33359936,"width":0.09042553,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"introduce-new-kiosk-login-features","depth":13,"bounds":{"left":0.47257313,"top":0.33359936,"width":0.09042553,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 22 checks OK","depth":13,"bounds":{"left":0.56432843,"top":0.33160415,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12084 opened","depth":13,"bounds":{"left":0.47257313,"top":0.35514766,"width":0.030751329,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 hour ago","depth":14,"bounds":{"left":0.50332445,"top":0.35514766,"width":0.019614361,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.52293885,"top":0.35514766,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny","depth":13,"bounds":{"left":0.529754,"top":0.35514766,"width":0.02244016,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by ilian-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ilian-jiminny","depth":14,"bounds":{"left":0.529754,"top":0.35514766,"width":0.02244016,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55352396,"top":0.35514766,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.55651593,"top":0.35514766,"width":0.03025266,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.55651593,"top":0.35514766,"width":0.03025266,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ilian-jiminny’s assigned issues","depth":13,"bounds":{"left":0.8090093,"top":0.3347965,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.3332003,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.3347965,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off","depth":12,"bounds":{"left":0.45462102,"top":0.38427773,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off","depth":12,"bounds":{"left":0.47257313,"top":0.38427773,"width":0.18633644,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off","depth":13,"bounds":{"left":0.47257313,"top":0.38427773,"width":0.18633644,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.66023934,"top":0.38188347,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12083 opened","depth":13,"bounds":{"left":0.47257313,"top":0.40582603,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17 hours ago","depth":14,"bounds":{"left":0.5031583,"top":0.40582603,"width":0.023936171,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.5270944,"top":0.40582603,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"mihailmihaylovjiminny","depth":13,"bounds":{"left":0.53390956,"top":0.40582603,"width":0.040724736,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by mihailmihaylovjiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":14,"bounds":{"left":0.53390956,"top":0.40582603,"width":0.040724736,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.5759641,"top":0.40582603,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.5789561,"top":0.40582603,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.5789561,"top":0.40582603,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.38347965,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.3850758,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20808 low priority indexing queue","depth":12,"bounds":{"left":0.45462102,"top":0.4349561,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20808 low priority indexing queue","depth":12,"bounds":{"left":0.47257313,"top":0.4349561,"width":0.09524601,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue","depth":13,"bounds":{"left":0.47257313,"top":0.4349561,"width":0.09524601,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"bounds":{"left":0.56914896,"top":0.43256184,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12082 opened","depth":13,"bounds":{"left":0.47257313,"top":0.45650437,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17 hours ago","depth":14,"bounds":{"left":0.5031583,"top":0.45650437,"width":0.023936171,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.5270944,"top":0.45650437,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"bounds":{"left":0.53390956,"top":0.45650437,"width":0.024933511,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"bounds":{"left":0.53390956,"top":0.45650437,"width":0.024933511,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.56017286,"top":0.45650437,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.5631649,"top":0.45650437,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.5631649,"top":0.45650437,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20900: fix calendar event deletion","depth":12,"bounds":{"left":0.45462102,"top":0.48563448,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20900: fix calendar event deletion","depth":12,"bounds":{"left":0.47257313,"top":0.48523542,"width":0.09541223,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20900: fix calendar event deletion","depth":13,"bounds":{"left":0.47257313,"top":0.48523542,"width":0.09541223,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"bounds":{"left":0.56914896,"top":0.48324022,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12079 opened","depth":13,"bounds":{"left":0.47257313,"top":0.5067837,"width":0.03025266,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20 hours ago","depth":14,"bounds":{"left":0.5028258,"top":0.5067837,"width":0.024767287,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.5275931,"top":0.5067837,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"TodorStamatovJiminny","depth":13,"bounds":{"left":0.5344083,"top":0.5067837,"width":0.04255319,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by TodorStamatovJiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"TodorStamatovJiminny","depth":14,"bounds":{"left":0.5344083,"top":0.5067837,"width":0.04255319,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.57829124,"top":0.5067837,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"bounds":{"left":0.5812833,"top":0.5067837,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"bounds":{"left":0.5812833,"top":0.5067837,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.4848364,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.48643255,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"WIP: JY-20853 | JY-20833 add paginated results, fix ES query, skip first result per…","depth":12,"bounds":{"left":0.45462102,"top":0.5359138,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"WIP: JY-20853 | JY-20833 add paginated results, fix ES query, skip first result per…","depth":12,"bounds":{"left":0.47257313,"top":0.5359138,"width":0.21276596,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"WIP: JY-20853 | JY-20833 add paginated results, fix ES query, skip first result per…","depth":13,"bounds":{"left":0.47257313,"top":0.5359138,"width":0.21276596,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.6866689,"top":0.53351957,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12076 opened","depth":13,"bounds":{"left":0.47257313,"top":0.5574621,"width":0.03025266,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"yesterday","depth":14,"bounds":{"left":0.5028258,"top":0.5574621,"width":0.018284574,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.52111036,"top":0.5574621,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":13,"bounds":{"left":0.52792555,"top":0.5574621,"width":0.02825798,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by yalokin-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":14,"bounds":{"left":0.52792555,"top":0.5574621,"width":0.02825798,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.5575133,"top":0.5574621,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.56050533,"top":0.5574621,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.56050533,"top":0.5574621,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"bounds":{"left":0.83826464,"top":0.5351157,"width":0.00930851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"bounds":{"left":0.84491354,"top":0.5367119,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20846 mcp enable the ai to know details about the user","depth":12,"bounds":{"left":0.45462102,"top":0.5865922,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20846 mcp enable the ai to know details about the user","depth":12,"bounds":{"left":0.47257313,"top":0.58619314,"width":0.14827128,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20846 mcp enable the ai to know details about the user","depth":13,"bounds":{"left":0.47257313,"top":0.58619314,"width":0.14827128,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"bounds":{"left":0.6221742,"top":0.58419794,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12075 opened","depth":13,"bounds":{"left":0.47257313,"top":0.6077414,"width":0.03025266,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 days ago","depth":14,"bounds":{"left":0.5028258,"top":0.6077414,"width":0.020279255,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.523105,"top":0.6077414,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"bounds":{"left":0.5299202,"top":0.6077414,"width":0.030751329,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"bounds":{"left":0.5299202,"top":0.6077414,"width":0.030751329,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.56200135,"top":0.6077414,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
3530297071535596123
|
8999535380190073990
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
30 Open
30 Open
10,998 Closed
10,998 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
JY-20671 Fix S3 For Twilio
9 / 11 checks OK
#12085 opened
15 minutes ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
introduce-new-kiosk-login-features
21 / 22 checks OK
#12084 opened
1 hour ago
by
ilian-jiminny
ilian-jiminny
•
Review required before merging
Review required
ilian-jiminny’s assigned issues
1 comment
1
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
JY-20911: Skip creating activity if setting 'Record Internal meetingс' is off
12 / 12 checks OK
#12083 opened
17 hours ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20808 low priority indexing queue
JY-20808 low priority indexing queue
JY-20808 low priority indexing queue
8 / 10 checks OK
#12082 opened
17 hours ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
JY-20900: fix calendar event deletion
JY-20900: fix calendar event deletion
JY-20900: fix calendar event deletion
12 / 13 checks OK
#12079 opened
20 hours ago
by
TodorStamatovJiminny
TodorStamatovJiminny
•
1 review approval
Approved
1 comment
1
WIP: JY-20853 | JY-20833 add paginated results, fix ES query, skip first result per…
WIP: JY-20853 | JY-20833 add paginated results, fix ES query, skip first result per…
WIP: JY-20853 | JY-20833 add paginated results, fix ES query, skip first result per…
12 / 12 checks OK
#12076 opened
yesterday
by
yalokin-jiminny
yalokin-jiminny
•
Draft
Draft
3 comments
3
Jy 20846 mcp enable the ai to know details about the user
Jy 20846 mcp enable the ai to know details about the user
Jy 20846 mcp enable the ai to know details about the user
8 / 10 checks OK
#12075 opened
2 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•...
|
47800
|
NULL
|
NULL
|
NULL
|
|
47803
|
1699
|
37
|
2026-05-15T08:53:22.442203+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835202442_m2.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls/LakyLak
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:open is:pr author:LakyLak
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
23 / 23 checks OK
#12066 opened
4 days ago
by
LakyLak
LakyLak
•
1 review approval
Approved
7 comments
7
Test hublets latency
Test hublets latency
Test hublets latency
22 / 23 checks OK
#11443 opened
on Dec 8, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
11 / 12 checks OK
#11327 opened
on Nov 10, 2025
by
LakyLak
LakyLak
•
Draft
Draft
9 comments
9
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
22 / 23 checks OK
#11197 opened
on Oct 13, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
24 / 25 checks OK
#11125 opened
on Sep 18, 2025
by
LakyLak
LakyLak
•
Draft
Draft
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
11 / 12 checks OK
#10810 opened
on Jun 19, 2025
by
LakyLak
LakyLak
•
1 review approval
Approved
1 comment
1
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
#9246 opened
on Jul 9, 2024
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
ProTip!
What’s not been updated in a month:
updated:<2026-04-15
updated:<2026-04-15
.
Footer
Footer
GitHub Homepage
© 2026 GitHub, Inc.
Footer navigation
Footer navigation
Terms
Terms
Privacy
Privacy
Security
Security
Status
Status
Community
Community
Docs
Docs
Contact
Contact
Manage cookies
Do not share my personal information
github.com/jiminny/app/pull/11443...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.38627294,"width":0.007978723,"height":0.01915403},"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.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.3020279,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.3020279,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.3073471,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.32197472,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.3352726,"top":0.06464485,"width":0.018949468,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.33726728,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.35920876,"top":0.06464485,"width":0.017785905,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.36120346,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.30169547,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.30169547,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.3073471,"top":0.09936153,"width":0.025099734,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.3181516,"top":0.10574621,"width":0.011469414,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"bounds":{"left":0.33510637,"top":0.09936153,"width":0.05518617,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.34574467,"top":0.10574621,"width":0.02925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.3776596,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"bounds":{"left":0.3806516,"top":0.113727055,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.38646942,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.3929521,"top":0.09936153,"width":0.029089095,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.4039229,"top":0.10574621,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.4247008,"top":0.09936153,"width":0.03025266,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.43583778,"top":0.10574621,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.45761302,"top":0.09936153,"width":0.022938829,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.46841756,"top":0.10574621,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"bounds":{"left":0.48321143,"top":0.09936153,"width":0.05817819,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.4950133,"top":0.10574621,"width":0.04255319,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.5440492,"top":0.09936153,"width":0.03125,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.55518615,"top":0.10574621,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.57795876,"top":0.09936153,"width":0.032081116,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.5890958,"top":0.10574621,"width":0.01761968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.31565824,"top":0.14365523,"width":0.0003324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.039228722,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.2159242,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.57214093,"top":0.1452514,"width":0.08261303,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.70694816,"top":0.1452514,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.13886672,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"bounds":{"left":0.44896942,"top":0.19553073,"width":0.04488032,"height":0.1452514},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.027426861,"height":0.025538707},"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":"Filters","depth":13,"bounds":{"left":0.45329124,"top":0.19752593,"width":0.013464096,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:open is:pr author:LakyLak","depth":11,"bounds":{"left":0.47606382,"top":0.1915403,"width":0.23105054,"height":0.025538707},"on_screen":true,"value":"is:open is:pr author:LakyLak","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"bounds":{"left":0.7124335,"top":0.1915403,"width":0.043218084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"bounds":{"left":0.7234042,"top":0.19752593,"width":0.016954787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"bounds":{"left":0.74268615,"top":0.1991221,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"bounds":{"left":0.7553192,"top":0.1915403,"width":0.049534574,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"bounds":{"left":0.7662899,"top":0.19752593,"width":0.026263298,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.79488033,"top":0.1991221,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"bounds":{"left":0.8075133,"top":0.1915403,"width":0.045711435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"bounds":{"left":0.8118351,"top":0.19752593,"width":0.03706782,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Clear current search query, filters, and sorts","depth":10,"bounds":{"left":0.44896942,"top":0.23144454,"width":0.10804521,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Clear current search query, filters, and sorts","depth":11,"bounds":{"left":0.45628324,"top":0.23144454,"width":0.10073138,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"bounds":{"left":0.45462102,"top":0.2753392,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"7 Open","depth":11,"bounds":{"left":0.46459442,"top":0.27294493,"width":0.023769947,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 Open","depth":12,"bounds":{"left":0.47124335,"top":0.2745411,"width":0.017121011,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"359 Closed","depth":11,"bounds":{"left":0.49301863,"top":0.27294493,"width":0.03274601,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"359 Closed","depth":12,"bounds":{"left":0.49966756,"top":0.2745411,"width":0.026097074,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"bounds":{"left":0.64045876,"top":0.27294493,"width":0.018284574,"height":0.016759777},"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":"Author","depth":12,"bounds":{"left":0.64045876,"top":0.2745411,"width":0.015625,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"bounds":{"left":0.6693817,"top":0.27294493,"width":0.015625,"height":0.016759777},"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":"Label","depth":12,"bounds":{"left":0.6693817,"top":0.2745411,"width":0.012965426,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"bounds":{"left":0.695645,"top":0.27294493,"width":0.02144282,"height":0.016759777},"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":"Projects","depth":13,"bounds":{"left":0.695645,"top":0.2745411,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","depth":12,"bounds":{"left":0.7290558,"top":0.27294493,"width":0.027260639,"height":0.016759777},"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":"Milestones","depth":13,"bounds":{"left":0.7290558,"top":0.2745411,"width":0.024601065,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","depth":12,"bounds":{"left":0.76828456,"top":0.27294493,"width":0.02144282,"height":0.016759777},"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":"Reviews","depth":13,"bounds":{"left":0.76828456,"top":0.2745411,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"bounds":{"left":0.8003657,"top":0.27294493,"width":0.0234375,"height":0.016759777},"on_screen":true,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"bounds":{"left":0.8003657,"top":0.2745411,"width":0.020777926,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"bounds":{"left":0.8344415,"top":0.27294493,"width":0.013131649,"height":0.016759777},"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":"Sort","depth":12,"bounds":{"left":0.8344415,"top":0.2745411,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"bounds":{"left":0.44930187,"top":0.30327216,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"bounds":{"left":0.44930187,"top":0.30606544,"width":0.03174867,"height":0.08060654},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20725 add HS rate limit handling on activities rematching","depth":12,"bounds":{"left":0.45462102,"top":0.31284916,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20725 add HS rate limit handling on activities rematching","depth":12,"bounds":{"left":0.47257313,"top":0.31284916,"width":0.1534242,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching","depth":13,"bounds":{"left":0.47257313,"top":0.31284916,"width":0.1534242,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"23 / 23 checks OK","depth":13,"bounds":{"left":0.62732714,"top":0.3104549,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12066 opened","depth":13,"bounds":{"left":0.47257313,"top":0.33439744,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"bounds":{"left":0.5031583,"top":0.33439744,"width":0.020611702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.52377,"top":0.33439744,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.5305851,"top":0.33439744,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.5305851,"top":0.33439744,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.54737365,"top":0.33439744,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"bounds":{"left":0.5503657,"top":0.33439744,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"bounds":{"left":0.5503657,"top":0.33439744,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"7 comments","depth":12,"bounds":{"left":0.8384308,"top":0.3120511,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7","depth":13,"bounds":{"left":0.8450798,"top":0.31364724,"width":0.002493351,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Test hublets latency","depth":12,"bounds":{"left":0.45462102,"top":0.36352754,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Test hublets latency","depth":12,"bounds":{"left":0.47257313,"top":0.36312848,"width":0.05069814,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Test hublets latency","depth":13,"bounds":{"left":0.47257313,"top":0.36312848,"width":0.05069814,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 23 checks OK","depth":13,"bounds":{"left":0.52460104,"top":0.36113328,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11443 opened","depth":13,"bounds":{"left":0.47257313,"top":0.38467678,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Dec 8, 2025","depth":14,"bounds":{"left":0.50265956,"top":0.38467678,"width":0.028922873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.5315825,"top":0.38467678,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.5383976,"top":0.38467678,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.5383976,"top":0.38467678,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55518615,"top":0.38467678,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.5581782,"top":0.38467678,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.5581782,"top":0.38467678,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.36272946,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.3643256,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-19501 webhook based opportunity sync","depth":12,"bounds":{"left":0.45462102,"top":0.41380686,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-19501 webhook based opportunity sync","depth":12,"bounds":{"left":0.47257313,"top":0.41380686,"width":0.109375,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-19501 webhook based opportunity sync","depth":13,"bounds":{"left":0.47257313,"top":0.41380686,"width":0.109375,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.58327794,"top":0.4114126,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11327 opened","depth":13,"bounds":{"left":0.47257313,"top":0.43535516,"width":0.029753989,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Nov 10, 2025","depth":14,"bounds":{"left":0.50232714,"top":0.43535516,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.53291225,"top":0.43535516,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.5397274,"top":0.43535516,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.5397274,"top":0.43535516,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55651593,"top":0.43535516,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.55950797,"top":0.43535516,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.55950797,"top":0.43535516,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"9 comments","depth":12,"bounds":{"left":0.83826464,"top":0.41300878,"width":0.00930851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9","depth":13,"bounds":{"left":0.84474736,"top":0.41460496,"width":0.0028257978,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 18908 streaming on chat abort","depth":12,"bounds":{"left":0.45462102,"top":0.46448523,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 18908 streaming on chat abort","depth":12,"bounds":{"left":0.47257313,"top":0.46448523,"width":0.085605055,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 18908 streaming on chat abort","depth":13,"bounds":{"left":0.47257313,"top":0.46448523,"width":0.085605055,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 23 checks OK","depth":13,"bounds":{"left":0.55950797,"top":0.46209097,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11197 opened","depth":13,"bounds":{"left":0.47257313,"top":0.48603353,"width":0.029089095,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Oct 13, 2025","depth":14,"bounds":{"left":0.50166225,"top":0.48603353,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.53174865,"top":0.48603353,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53856385,"top":0.48603353,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53856385,"top":0.48603353,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55518615,"top":0.48603353,"width":0.0031582448,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.5583444,"top":0.48603353,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.5583444,"top":0.48603353,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.46368715,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.46528333,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-18750 debug logs for OD data loading","depth":12,"bounds":{"left":0.45462102,"top":0.5151636,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-18750 debug logs for OD data loading","depth":12,"bounds":{"left":0.47257313,"top":0.51476455,"width":0.104222074,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-18750 debug logs for OD data loading","depth":13,"bounds":{"left":0.47257313,"top":0.51476455,"width":0.104222074,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"24 / 25 checks OK","depth":13,"bounds":{"left":0.578125,"top":0.51276934,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11125 opened","depth":13,"bounds":{"left":0.47257313,"top":0.5363129,"width":0.02925532,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Sep 18, 2025","depth":14,"bounds":{"left":0.50182843,"top":0.5363129,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.53241354,"top":0.5363129,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53922874,"top":0.5363129,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53922874,"top":0.5363129,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55585104,"top":0.5363129,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.5588431,"top":0.5363129,"width":0.009640957,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.5588431,"top":0.5363129,"width":0.009640957,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-17640 push data to Dynamics","depth":12,"bounds":{"left":0.45462102,"top":0.5654429,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-17640 push data to Dynamics","depth":12,"bounds":{"left":0.47257313,"top":0.5654429,"width":0.08361037,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-17640 push data to Dynamics","depth":13,"bounds":{"left":0.47257313,"top":0.5654429,"width":0.08361037,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.5575133,"top":0.56304866,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#10810 opened","depth":13,"bounds":{"left":0.47257313,"top":0.58699125,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Jun 19, 2025","depth":14,"bounds":{"left":0.50265956,"top":0.58699125,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.532746,"top":0.58699125,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53956115,"top":0.58699125,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53956115,"top":0.58699125,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55634975,"top":0.58699125,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"bounds":{"left":0.5593417,"top":0.58699125,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"bounds":{"left":0.5593417,"top":0.58699125,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.5646449,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.566241,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-13692 add after parameter to opportunity sync for HS","depth":12,"bounds":{"left":0.45462102,"top":0.6161213,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-13692 add after parameter to opportunity sync for HS","depth":12,"bounds":{"left":0.47257313,"top":0.61572224,"width":0.14478059,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-13692 add after parameter to opportunity sync for HS","depth":13,"bounds":{"left":0.47257313,"top":0.61572224,"width":0.14478059,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#9246 opened","depth":13,"bounds":{"left":0.47257313,"top":0.63727057,"width":0.028756648,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Jul 9, 2024","depth":14,"bounds":{"left":0.5013298,"top":0.63727057,"width":0.026928192,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.52825797,"top":0.63727057,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53507316,"top":0.63727057,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53507316,"top":0.63727057,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.5518617,"top":0.63727057,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.55485374,"top":0.63727057,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.55485374,"top":0.63727057,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.61532325,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.6169194,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ProTip!","depth":11,"bounds":{"left":0.5806183,"top":0.6847566,"width":0.015791224,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"What’s not been updated in a month:","depth":10,"bounds":{"left":0.59640956,"top":0.6847566,"width":0.08211436,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"updated:<2026-04-15","depth":10,"bounds":{"left":0.67852396,"top":0.6847566,"width":0.048204787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"updated:<2026-04-15","depth":11,"bounds":{"left":0.67852396,"top":0.6847566,"width":0.048204787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.72672874,"top":0.6847566,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Footer","depth":7,"bounds":{"left":0.3073471,"top":0.73822826,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Footer","depth":8,"bounds":{"left":0.3073471,"top":0.7410216,"width":0.0234375,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub Homepage","depth":7,"bounds":{"left":0.50299203,"top":0.73822826,"width":0.007978723,"height":0.020351157},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"© 2026 GitHub, Inc.","depth":8,"bounds":{"left":0.51363033,"top":0.7426177,"width":0.037898935,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Footer navigation","depth":8,"bounds":{"left":0.55418885,"top":0.74142057,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Footer navigation","depth":9,"bounds":{"left":0.55418885,"top":0.7438148,"width":0.03174867,"height":0.04309657},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms","depth":10,"bounds":{"left":0.5568484,"top":0.7426177,"width":0.011469414,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms","depth":11,"bounds":{"left":0.5568484,"top":0.7426177,"width":0.011469414,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Privacy","depth":10,"bounds":{"left":0.57363695,"top":0.7426177,"width":0.013796543,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Privacy","depth":11,"bounds":{"left":0.57363695,"top":0.7426177,"width":0.013796543,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security","depth":10,"bounds":{"left":0.59275264,"top":0.7426177,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security","depth":11,"bounds":{"left":0.59275264,"top":0.7426177,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Status","depth":10,"bounds":{"left":0.6135306,"top":0.7426177,"width":0.012134309,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":11,"bounds":{"left":0.6135306,"top":0.7426177,"width":0.012134309,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Community","depth":10,"bounds":{"left":0.63098407,"top":0.7426177,"width":0.021276595,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Community","depth":11,"bounds":{"left":0.63098407,"top":0.7426177,"width":0.021276595,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Docs","depth":10,"bounds":{"left":0.6575798,"top":0.7426177,"width":0.009640957,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Docs","depth":11,"bounds":{"left":0.6575798,"top":0.7426177,"width":0.009640957,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Contact","depth":10,"bounds":{"left":0.6725399,"top":0.7426177,"width":0.014960106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Contact","depth":11,"bounds":{"left":0.6725399,"top":0.7426177,"width":0.014960106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Manage cookies","depth":11,"bounds":{"left":0.6928192,"top":0.74142057,"width":0.030418882,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Do not share my personal information","depth":11,"bounds":{"left":0.72855717,"top":0.74142057,"width":0.07047872,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"github.com/jiminny/app/pull/11443","depth":5,"bounds":{"left":0.30335772,"top":0.9876297,"width":0.059507977,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
5645417941493340012
|
6065344758180142860
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:open is:pr author:LakyLak
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
23 / 23 checks OK
#12066 opened
4 days ago
by
LakyLak
LakyLak
•
1 review approval
Approved
7 comments
7
Test hublets latency
Test hublets latency
Test hublets latency
22 / 23 checks OK
#11443 opened
on Dec 8, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
11 / 12 checks OK
#11327 opened
on Nov 10, 2025
by
LakyLak
LakyLak
•
Draft
Draft
9 comments
9
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
22 / 23 checks OK
#11197 opened
on Oct 13, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
24 / 25 checks OK
#11125 opened
on Sep 18, 2025
by
LakyLak
LakyLak
•
Draft
Draft
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
11 / 12 checks OK
#10810 opened
on Jun 19, 2025
by
LakyLak
LakyLak
•
1 review approval
Approved
1 comment
1
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
#9246 opened
on Jul 9, 2024
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
ProTip!
What’s not been updated in a month:
updated:<2026-04-15
updated:<2026-04-15
.
Footer
Footer
GitHub Homepage
© 2026 GitHub, Inc.
Footer navigation
Footer navigation
Terms
Terms
Privacy
Privacy
Security
Security
Status
Status
Community
Community
Docs
Docs
Contact
Contact
Manage cookies
Do not share my personal information
github.com/jiminny/app/pull/11443...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47804
|
1698
|
26
|
2026-05-15T08:53:24.728942+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835204728_m1.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls/LakyLak
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:open is:pr author:LakyLak
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
23 / 23 checks OK
#12066 opened
4 days ago
by
LakyLak
LakyLak
•
1 review approval
Approved
7 comments
7
Test hublets latency
Test hublets latency
Test hublets latency
22 / 23 checks OK
#11443 opened
on Dec 8, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
11 / 12 checks OK
#11327 opened
on Nov 10, 2025
by
LakyLak
LakyLak
•
Draft
Draft
9 comments
9
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
22 / 23 checks OK
#11197 opened
on Oct 13, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
24 / 25 checks OK
#11125 opened
on Sep 18, 2025
by
LakyLak
LakyLak
•
Draft
Draft
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
11 / 12 checks OK
#10810 opened
on Jun 19, 2025
by
LakyLak
LakyLak
•
1 review approval
Approved
1 comment
1
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
#9246 opened
on Jul 9, 2024
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
ProTip!
What’s not been updated in a month:
updated:<2026-04-15
updated:<2026-04-15
.
Footer
Footer
GitHub Homepage
© 2026 GitHub, Inc.
Footer navigation
Footer navigation
Terms
Terms
Privacy
Privacy
Security
Security
Status
Status
Community
Community
Docs
Docs
Contact
Contact
Manage cookies
Do not share my personal information...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"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,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"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":"Filters","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:open is:pr author:LakyLak","depth":11,"on_screen":true,"value":"is:open is:pr author:LakyLak","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Clear current search query, filters, and sorts","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Clear current search query, filters, and sorts","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"7 Open","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 Open","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"359 Closed","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"359 Closed","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"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":"Author","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"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":"Label","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","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":"Projects","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","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":"Milestones","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","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":"Reviews","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"on_screen":true,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"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":"Sort","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20725 add HS rate limit handling on activities rematching","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20725 add HS rate limit handling on activities rematching","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"23 / 23 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12066 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"7 comments","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Test hublets latency","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Test hublets latency","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Test hublets latency","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 23 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11443 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Dec 8, 2025","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-19501 webhook based opportunity sync","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-19501 webhook based opportunity sync","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-19501 webhook based opportunity sync","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11327 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Nov 10, 2025","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"9 comments","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 18908 streaming on chat abort","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 18908 streaming on chat abort","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 18908 streaming on chat abort","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 23 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11197 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Oct 13, 2025","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-18750 debug logs for OD data loading","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-18750 debug logs for OD data loading","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-18750 debug logs for OD data loading","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"24 / 25 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11125 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Sep 18, 2025","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-17640 push data to Dynamics","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-17640 push data to Dynamics","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-17640 push data to Dynamics","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#10810 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Jun 19, 2025","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-13692 add after parameter to opportunity sync for HS","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-13692 add after parameter to opportunity sync for HS","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-13692 add after parameter to opportunity sync for HS","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#9246 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Jul 9, 2024","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ProTip!","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"What’s not been updated in a month:","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"updated:<2026-04-15","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"updated:<2026-04-15","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Footer","depth":7,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Footer","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub Homepage","depth":7,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"© 2026 GitHub, Inc.","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Footer navigation","depth":8,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Footer navigation","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Privacy","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Privacy","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Status","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Community","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Community","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Docs","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Docs","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Contact","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Contact","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Manage cookies","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Do not share my personal information","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
150768458391842861
|
6065344758180142860
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:open is:pr author:LakyLak
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
23 / 23 checks OK
#12066 opened
4 days ago
by
LakyLak
LakyLak
•
1 review approval
Approved
7 comments
7
Test hublets latency
Test hublets latency
Test hublets latency
22 / 23 checks OK
#11443 opened
on Dec 8, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
11 / 12 checks OK
#11327 opened
on Nov 10, 2025
by
LakyLak
LakyLak
•
Draft
Draft
9 comments
9
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
22 / 23 checks OK
#11197 opened
on Oct 13, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
24 / 25 checks OK
#11125 opened
on Sep 18, 2025
by
LakyLak
LakyLak
•
Draft
Draft
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
11 / 12 checks OK
#10810 opened
on Jun 19, 2025
by
LakyLak
LakyLak
•
1 review approval
Approved
1 comment
1
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
#9246 opened
on Jul 9, 2024
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
ProTip!
What’s not been updated in a month:
updated:<2026-04-15
updated:<2026-04-15
.
Footer
Footer
GitHub Homepage
© 2026 GitHub, Inc.
Footer navigation
Footer navigation
Terms
Terms
Privacy
Privacy
Security
Security
Status
Status
Community
Community
Docs
Docs
Contact
Contact
Manage cookies
Do not share my personal information...
|
47801
|
NULL
|
NULL
|
NULL
|
|
47805
|
1699
|
38
|
2026-05-15T08:53:24.762878+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835204762_m2.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls/LakyLak
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:open is:pr author:LakyLak
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
23 / 23 checks OK
#12066 opened
4 days ago
by
LakyLak
LakyLak
•
1 review approval
Approved
7 comments
7
Test hublets latency
Test hublets latency
Test hublets latency
22 / 23 checks OK
#11443 opened
on Dec 8, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
11 / 12 checks OK
#11327 opened
on Nov 10, 2025
by
LakyLak
LakyLak
•
Draft
Draft
9 comments
9
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
22 / 23 checks OK
#11197 opened
on Oct 13, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
24 / 25 checks OK
#11125 opened
on Sep 18, 2025
by
LakyLak
LakyLak
•
Draft
Draft
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
11 / 12 checks OK
#10810 opened
on Jun 19, 2025
by
LakyLak
LakyLak
•
1 review approval
Approved
1 comment
1
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
#9246 opened
on Jul 9, 2024
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
ProTip!
What’s not been updated in a month:
updated:<2026-04-15
updated:<2026-04-15
.
Footer
Footer
GitHub Homepage
© 2026 GitHub, Inc.
Footer navigation
Footer navigation
Terms
Terms
Privacy
Privacy
Security
Security
Status
Status
Community
Community
Docs
Docs
Contact
Contact
Manage cookies
Do not share my personal information...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.38627294,"width":0.007978723,"height":0.01915403},"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.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.3020279,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.3020279,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.3073471,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.32197472,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.3352726,"top":0.06464485,"width":0.018949468,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.33726728,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.35920876,"top":0.06464485,"width":0.017785905,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.36120346,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.30169547,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.30169547,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.3073471,"top":0.09936153,"width":0.025099734,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.3181516,"top":0.10574621,"width":0.011469414,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"bounds":{"left":0.33510637,"top":0.09936153,"width":0.05518617,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.34574467,"top":0.10574621,"width":0.02925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.3776596,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"bounds":{"left":0.3806516,"top":0.113727055,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.38646942,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.3929521,"top":0.09936153,"width":0.029089095,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.4039229,"top":0.10574621,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.4247008,"top":0.09936153,"width":0.03025266,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.43583778,"top":0.10574621,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.45761302,"top":0.09936153,"width":0.022938829,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.46841756,"top":0.10574621,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"bounds":{"left":0.48321143,"top":0.09936153,"width":0.05817819,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.4950133,"top":0.10574621,"width":0.04255319,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.5440492,"top":0.09936153,"width":0.03125,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.55518615,"top":0.10574621,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.57795876,"top":0.09936153,"width":0.032081116,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.5890958,"top":0.10574621,"width":0.01761968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.31565824,"top":0.14365523,"width":0.0003324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.039228722,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.2159242,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.57214093,"top":0.1452514,"width":0.08261303,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.70694816,"top":0.1452514,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.13886672,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"bounds":{"left":0.44896942,"top":0.19553073,"width":0.04488032,"height":0.1452514},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.027426861,"height":0.025538707},"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":"Filters","depth":13,"bounds":{"left":0.45329124,"top":0.19752593,"width":0.013464096,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:open is:pr author:LakyLak","depth":11,"bounds":{"left":0.47606382,"top":0.1915403,"width":0.23105054,"height":0.025538707},"on_screen":true,"value":"is:open is:pr author:LakyLak","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"bounds":{"left":0.7124335,"top":0.1915403,"width":0.043218084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"bounds":{"left":0.7234042,"top":0.19752593,"width":0.016954787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"bounds":{"left":0.74268615,"top":0.1991221,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"bounds":{"left":0.7553192,"top":0.1915403,"width":0.049534574,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"bounds":{"left":0.7662899,"top":0.19752593,"width":0.026263298,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.79488033,"top":0.1991221,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"bounds":{"left":0.8075133,"top":0.1915403,"width":0.045711435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"bounds":{"left":0.8118351,"top":0.19752593,"width":0.03706782,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Clear current search query, filters, and sorts","depth":10,"bounds":{"left":0.44896942,"top":0.23144454,"width":0.10804521,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Clear current search query, filters, and sorts","depth":11,"bounds":{"left":0.45628324,"top":0.23144454,"width":0.10073138,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"bounds":{"left":0.45462102,"top":0.2753392,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"7 Open","depth":11,"bounds":{"left":0.46459442,"top":0.27294493,"width":0.023769947,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 Open","depth":12,"bounds":{"left":0.47124335,"top":0.2745411,"width":0.017121011,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"359 Closed","depth":11,"bounds":{"left":0.49301863,"top":0.27294493,"width":0.03274601,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"359 Closed","depth":12,"bounds":{"left":0.49966756,"top":0.2745411,"width":0.026097074,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"bounds":{"left":0.64045876,"top":0.27294493,"width":0.018284574,"height":0.016759777},"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":"Author","depth":12,"bounds":{"left":0.64045876,"top":0.2745411,"width":0.015625,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"bounds":{"left":0.6693817,"top":0.27294493,"width":0.015625,"height":0.016759777},"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":"Label","depth":12,"bounds":{"left":0.6693817,"top":0.2745411,"width":0.012965426,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"bounds":{"left":0.695645,"top":0.27294493,"width":0.02144282,"height":0.016759777},"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":"Projects","depth":13,"bounds":{"left":0.695645,"top":0.2745411,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","depth":12,"bounds":{"left":0.7290558,"top":0.27294493,"width":0.027260639,"height":0.016759777},"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":"Milestones","depth":13,"bounds":{"left":0.7290558,"top":0.2745411,"width":0.024601065,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","depth":12,"bounds":{"left":0.76828456,"top":0.27294493,"width":0.02144282,"height":0.016759777},"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":"Reviews","depth":13,"bounds":{"left":0.76828456,"top":0.2745411,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"bounds":{"left":0.8003657,"top":0.27294493,"width":0.0234375,"height":0.016759777},"on_screen":true,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"bounds":{"left":0.8003657,"top":0.2745411,"width":0.020777926,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"bounds":{"left":0.8344415,"top":0.27294493,"width":0.013131649,"height":0.016759777},"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":"Sort","depth":12,"bounds":{"left":0.8344415,"top":0.2745411,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"bounds":{"left":0.44930187,"top":0.30327216,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"bounds":{"left":0.44930187,"top":0.30606544,"width":0.03174867,"height":0.08060654},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20725 add HS rate limit handling on activities rematching","depth":12,"bounds":{"left":0.45462102,"top":0.31284916,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20725 add HS rate limit handling on activities rematching","depth":12,"bounds":{"left":0.47257313,"top":0.31284916,"width":0.1534242,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching","depth":13,"bounds":{"left":0.47257313,"top":0.31284916,"width":0.1534242,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"23 / 23 checks OK","depth":13,"bounds":{"left":0.62732714,"top":0.3104549,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12066 opened","depth":13,"bounds":{"left":0.47257313,"top":0.33439744,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"bounds":{"left":0.5031583,"top":0.33439744,"width":0.020611702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.52377,"top":0.33439744,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.5305851,"top":0.33439744,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.5305851,"top":0.33439744,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.54737365,"top":0.33439744,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"bounds":{"left":0.5503657,"top":0.33439744,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"bounds":{"left":0.5503657,"top":0.33439744,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"7 comments","depth":12,"bounds":{"left":0.8384308,"top":0.3120511,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7","depth":13,"bounds":{"left":0.8450798,"top":0.31364724,"width":0.002493351,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Test hublets latency","depth":12,"bounds":{"left":0.45462102,"top":0.36352754,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Test hublets latency","depth":12,"bounds":{"left":0.47257313,"top":0.36312848,"width":0.05069814,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Test hublets latency","depth":13,"bounds":{"left":0.47257313,"top":0.36312848,"width":0.05069814,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 23 checks OK","depth":13,"bounds":{"left":0.52460104,"top":0.36113328,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11443 opened","depth":13,"bounds":{"left":0.47257313,"top":0.38467678,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Dec 8, 2025","depth":14,"bounds":{"left":0.50265956,"top":0.38467678,"width":0.028922873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.5315825,"top":0.38467678,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.5383976,"top":0.38467678,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.5383976,"top":0.38467678,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55518615,"top":0.38467678,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.5581782,"top":0.38467678,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.5581782,"top":0.38467678,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.36272946,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.3643256,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-19501 webhook based opportunity sync","depth":12,"bounds":{"left":0.45462102,"top":0.41380686,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-19501 webhook based opportunity sync","depth":12,"bounds":{"left":0.47257313,"top":0.41380686,"width":0.109375,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-19501 webhook based opportunity sync","depth":13,"bounds":{"left":0.47257313,"top":0.41380686,"width":0.109375,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.58327794,"top":0.4114126,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11327 opened","depth":13,"bounds":{"left":0.47257313,"top":0.43535516,"width":0.029753989,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Nov 10, 2025","depth":14,"bounds":{"left":0.50232714,"top":0.43535516,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.53291225,"top":0.43535516,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.5397274,"top":0.43535516,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.5397274,"top":0.43535516,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55651593,"top":0.43535516,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.55950797,"top":0.43535516,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.55950797,"top":0.43535516,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"9 comments","depth":12,"bounds":{"left":0.83826464,"top":0.41300878,"width":0.00930851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9","depth":13,"bounds":{"left":0.84474736,"top":0.41460496,"width":0.0028257978,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 18908 streaming on chat abort","depth":12,"bounds":{"left":0.45462102,"top":0.46448523,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 18908 streaming on chat abort","depth":12,"bounds":{"left":0.47257313,"top":0.46448523,"width":0.085605055,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 18908 streaming on chat abort","depth":13,"bounds":{"left":0.47257313,"top":0.46448523,"width":0.085605055,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 23 checks OK","depth":13,"bounds":{"left":0.55950797,"top":0.46209097,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11197 opened","depth":13,"bounds":{"left":0.47257313,"top":0.48603353,"width":0.029089095,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Oct 13, 2025","depth":14,"bounds":{"left":0.50166225,"top":0.48603353,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.53174865,"top":0.48603353,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53856385,"top":0.48603353,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53856385,"top":0.48603353,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55518615,"top":0.48603353,"width":0.0031582448,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.5583444,"top":0.48603353,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.5583444,"top":0.48603353,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.46368715,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.46528333,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-18750 debug logs for OD data loading","depth":12,"bounds":{"left":0.45462102,"top":0.5151636,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-18750 debug logs for OD data loading","depth":12,"bounds":{"left":0.47257313,"top":0.51476455,"width":0.104222074,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-18750 debug logs for OD data loading","depth":13,"bounds":{"left":0.47257313,"top":0.51476455,"width":0.104222074,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"24 / 25 checks OK","depth":13,"bounds":{"left":0.578125,"top":0.51276934,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11125 opened","depth":13,"bounds":{"left":0.47257313,"top":0.5363129,"width":0.02925532,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Sep 18, 2025","depth":14,"bounds":{"left":0.50182843,"top":0.5363129,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.53241354,"top":0.5363129,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53922874,"top":0.5363129,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53922874,"top":0.5363129,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55585104,"top":0.5363129,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.5588431,"top":0.5363129,"width":0.009640957,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.5588431,"top":0.5363129,"width":0.009640957,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-17640 push data to Dynamics","depth":12,"bounds":{"left":0.45462102,"top":0.5654429,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-17640 push data to Dynamics","depth":12,"bounds":{"left":0.47257313,"top":0.5654429,"width":0.08361037,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-17640 push data to Dynamics","depth":13,"bounds":{"left":0.47257313,"top":0.5654429,"width":0.08361037,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.5575133,"top":0.56304866,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#10810 opened","depth":13,"bounds":{"left":0.47257313,"top":0.58699125,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Jun 19, 2025","depth":14,"bounds":{"left":0.50265956,"top":0.58699125,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.532746,"top":0.58699125,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53956115,"top":0.58699125,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53956115,"top":0.58699125,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55634975,"top":0.58699125,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"bounds":{"left":0.5593417,"top":0.58699125,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"bounds":{"left":0.5593417,"top":0.58699125,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.5646449,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.566241,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-13692 add after parameter to opportunity sync for HS","depth":12,"bounds":{"left":0.45462102,"top":0.6161213,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-13692 add after parameter to opportunity sync for HS","depth":12,"bounds":{"left":0.47257313,"top":0.61572224,"width":0.14478059,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-13692 add after parameter to opportunity sync for HS","depth":13,"bounds":{"left":0.47257313,"top":0.61572224,"width":0.14478059,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#9246 opened","depth":13,"bounds":{"left":0.47257313,"top":0.63727057,"width":0.028756648,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Jul 9, 2024","depth":14,"bounds":{"left":0.5013298,"top":0.63727057,"width":0.026928192,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.52825797,"top":0.63727057,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53507316,"top":0.63727057,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53507316,"top":0.63727057,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.5518617,"top":0.63727057,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.55485374,"top":0.63727057,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.55485374,"top":0.63727057,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.61532325,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.6169194,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ProTip!","depth":11,"bounds":{"left":0.5806183,"top":0.6847566,"width":0.015791224,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"What’s not been updated in a month:","depth":10,"bounds":{"left":0.59640956,"top":0.6847566,"width":0.08211436,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"updated:<2026-04-15","depth":10,"bounds":{"left":0.67852396,"top":0.6847566,"width":0.048204787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"updated:<2026-04-15","depth":11,"bounds":{"left":0.67852396,"top":0.6847566,"width":0.048204787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.72672874,"top":0.6847566,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Footer","depth":7,"bounds":{"left":0.3073471,"top":0.73822826,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Footer","depth":8,"bounds":{"left":0.3073471,"top":0.7410216,"width":0.0234375,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub Homepage","depth":7,"bounds":{"left":0.50299203,"top":0.73822826,"width":0.007978723,"height":0.020351157},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"© 2026 GitHub, Inc.","depth":8,"bounds":{"left":0.51363033,"top":0.7426177,"width":0.037898935,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Footer navigation","depth":8,"bounds":{"left":0.55418885,"top":0.74142057,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Footer navigation","depth":9,"bounds":{"left":0.55418885,"top":0.7438148,"width":0.03174867,"height":0.04309657},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms","depth":10,"bounds":{"left":0.5568484,"top":0.7426177,"width":0.011469414,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms","depth":11,"bounds":{"left":0.5568484,"top":0.7426177,"width":0.011469414,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Privacy","depth":10,"bounds":{"left":0.57363695,"top":0.7426177,"width":0.013796543,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Privacy","depth":11,"bounds":{"left":0.57363695,"top":0.7426177,"width":0.013796543,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security","depth":10,"bounds":{"left":0.59275264,"top":0.7426177,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security","depth":11,"bounds":{"left":0.59275264,"top":0.7426177,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Status","depth":10,"bounds":{"left":0.6135306,"top":0.7426177,"width":0.012134309,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":11,"bounds":{"left":0.6135306,"top":0.7426177,"width":0.012134309,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Community","depth":10,"bounds":{"left":0.63098407,"top":0.7426177,"width":0.021276595,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Community","depth":11,"bounds":{"left":0.63098407,"top":0.7426177,"width":0.021276595,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Docs","depth":10,"bounds":{"left":0.6575798,"top":0.7426177,"width":0.009640957,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Docs","depth":11,"bounds":{"left":0.6575798,"top":0.7426177,"width":0.009640957,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Contact","depth":10,"bounds":{"left":0.6725399,"top":0.7426177,"width":0.014960106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Contact","depth":11,"bounds":{"left":0.6725399,"top":0.7426177,"width":0.014960106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Manage cookies","depth":11,"bounds":{"left":0.6928192,"top":0.74142057,"width":0.030418882,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Do not share my personal information","depth":11,"bounds":{"left":0.72855717,"top":0.74142057,"width":0.07047872,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
150768458391842861
|
6065344758180142860
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:open is:pr author:LakyLak
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
23 / 23 checks OK
#12066 opened
4 days ago
by
LakyLak
LakyLak
•
1 review approval
Approved
7 comments
7
Test hublets latency
Test hublets latency
Test hublets latency
22 / 23 checks OK
#11443 opened
on Dec 8, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
11 / 12 checks OK
#11327 opened
on Nov 10, 2025
by
LakyLak
LakyLak
•
Draft
Draft
9 comments
9
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
22 / 23 checks OK
#11197 opened
on Oct 13, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
24 / 25 checks OK
#11125 opened
on Sep 18, 2025
by
LakyLak
LakyLak
•
Draft
Draft
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
11 / 12 checks OK
#10810 opened
on Jun 19, 2025
by
LakyLak
LakyLak
•
1 review approval
Approved
1 comment
1
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
#9246 opened
on Jul 9, 2024
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
ProTip!
What’s not been updated in a month:
updated:<2026-04-15
updated:<2026-04-15
.
Footer
Footer
GitHub Homepage
© 2026 GitHub, Inc.
Footer navigation
Footer navigation
Terms
Terms
Privacy
Privacy
Security
Security
Status
Status
Community
Community
Docs
Docs
Contact
Contact
Manage cookies
Do not share my personal information...
|
47803
|
NULL
|
NULL
|
NULL
|
|
47807
|
1699
|
39
|
2026-05-15T08:53:27.399911+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835207399_m2.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls/LakyLak
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:open is:pr author:LakyLak
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
23 / 23 checks OK
#12066 opened
4 days ago
by
LakyLak
LakyLak
•
1 review approval
Approved
7 comments
7
Test hublets latency
Test hublets latency
Test hublets latency
22 / 23 checks OK
#11443 opened
on Dec 8, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
11 / 12 checks OK
#11327 opened
on Nov 10, 2025
by
LakyLak
LakyLak
•
Draft
Draft
9 comments
9
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
22 / 23 checks OK
#11197 opened
on Oct 13, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
24 / 25 checks OK
#11125 opened
on Sep 18, 2025
by
LakyLak
LakyLak
•
Draft
Draft
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
11 / 12 checks OK
#10810 opened
on Jun 19, 2025
by
LakyLak
LakyLak
•
1 review approval
Approved
1 comment
1
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
#9246 opened
on Jul 9, 2024
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
ProTip!
What’s not been updated in a month:
updated:<2026-04-15...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.38627294,"width":0.007978723,"height":0.01915403},"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.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.3020279,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.3020279,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.3073471,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.32197472,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.3352726,"top":0.06464485,"width":0.018949468,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.33726728,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.35920876,"top":0.06464485,"width":0.017785905,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.36120346,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.30169547,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.30169547,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.3073471,"top":0.09936153,"width":0.025099734,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.3181516,"top":0.10574621,"width":0.011469414,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"bounds":{"left":0.33510637,"top":0.09936153,"width":0.05518617,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.34574467,"top":0.10574621,"width":0.02925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.3776596,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"bounds":{"left":0.3806516,"top":0.113727055,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.38646942,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.3929521,"top":0.09936153,"width":0.029089095,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.4039229,"top":0.10574621,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.4247008,"top":0.09936153,"width":0.03025266,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.43583778,"top":0.10574621,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.45761302,"top":0.09936153,"width":0.022938829,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.46841756,"top":0.10574621,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"bounds":{"left":0.48321143,"top":0.09936153,"width":0.05817819,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.4950133,"top":0.10574621,"width":0.04255319,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.5440492,"top":0.09936153,"width":0.03125,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.55518615,"top":0.10574621,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.57795876,"top":0.09936153,"width":0.032081116,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.5890958,"top":0.10574621,"width":0.01761968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.31565824,"top":0.14365523,"width":0.0003324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.039228722,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.2159242,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.57214093,"top":0.1452514,"width":0.08261303,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.70694816,"top":0.1452514,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.13886672,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"bounds":{"left":0.44896942,"top":0.19553073,"width":0.04488032,"height":0.1452514},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.027426861,"height":0.025538707},"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":"Filters","depth":13,"bounds":{"left":0.45329124,"top":0.19752593,"width":0.013464096,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:open is:pr author:LakyLak","depth":11,"bounds":{"left":0.47606382,"top":0.1915403,"width":0.23105054,"height":0.025538707},"on_screen":true,"value":"is:open is:pr author:LakyLak","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"bounds":{"left":0.7124335,"top":0.1915403,"width":0.043218084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"bounds":{"left":0.7234042,"top":0.19752593,"width":0.016954787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"bounds":{"left":0.74268615,"top":0.1991221,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"bounds":{"left":0.7553192,"top":0.1915403,"width":0.049534574,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"bounds":{"left":0.7662899,"top":0.19752593,"width":0.026263298,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.79488033,"top":0.1991221,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"bounds":{"left":0.8075133,"top":0.1915403,"width":0.045711435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"bounds":{"left":0.8118351,"top":0.19752593,"width":0.03706782,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Clear current search query, filters, and sorts","depth":10,"bounds":{"left":0.44896942,"top":0.23144454,"width":0.10804521,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Clear current search query, filters, and sorts","depth":11,"bounds":{"left":0.45628324,"top":0.23144454,"width":0.10073138,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"bounds":{"left":0.45462102,"top":0.2753392,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"7 Open","depth":11,"bounds":{"left":0.46459442,"top":0.27294493,"width":0.023769947,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 Open","depth":12,"bounds":{"left":0.47124335,"top":0.2745411,"width":0.017121011,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"359 Closed","depth":11,"bounds":{"left":0.49301863,"top":0.27294493,"width":0.03274601,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"359 Closed","depth":12,"bounds":{"left":0.49966756,"top":0.2745411,"width":0.026097074,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"bounds":{"left":0.64045876,"top":0.27294493,"width":0.018284574,"height":0.016759777},"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":"Author","depth":12,"bounds":{"left":0.64045876,"top":0.2745411,"width":0.015625,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"bounds":{"left":0.6693817,"top":0.27294493,"width":0.015625,"height":0.016759777},"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":"Label","depth":12,"bounds":{"left":0.6693817,"top":0.2745411,"width":0.012965426,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"bounds":{"left":0.695645,"top":0.27294493,"width":0.02144282,"height":0.016759777},"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":"Projects","depth":13,"bounds":{"left":0.695645,"top":0.2745411,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","depth":12,"bounds":{"left":0.7290558,"top":0.27294493,"width":0.027260639,"height":0.016759777},"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":"Milestones","depth":13,"bounds":{"left":0.7290558,"top":0.2745411,"width":0.024601065,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","depth":12,"bounds":{"left":0.76828456,"top":0.27294493,"width":0.02144282,"height":0.016759777},"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":"Reviews","depth":13,"bounds":{"left":0.76828456,"top":0.2745411,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"bounds":{"left":0.8003657,"top":0.27294493,"width":0.0234375,"height":0.016759777},"on_screen":true,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"bounds":{"left":0.8003657,"top":0.2745411,"width":0.020777926,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"bounds":{"left":0.8344415,"top":0.27294493,"width":0.013131649,"height":0.016759777},"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":"Sort","depth":12,"bounds":{"left":0.8344415,"top":0.2745411,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"bounds":{"left":0.44930187,"top":0.30327216,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"bounds":{"left":0.44930187,"top":0.30606544,"width":0.03174867,"height":0.08060654},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20725 add HS rate limit handling on activities rematching","depth":12,"bounds":{"left":0.45462102,"top":0.31284916,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20725 add HS rate limit handling on activities rematching","depth":12,"bounds":{"left":0.47257313,"top":0.31284916,"width":0.1534242,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching","depth":13,"bounds":{"left":0.47257313,"top":0.31284916,"width":0.1534242,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"23 / 23 checks OK","depth":13,"bounds":{"left":0.62732714,"top":0.3104549,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12066 opened","depth":13,"bounds":{"left":0.47257313,"top":0.33439744,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"bounds":{"left":0.5031583,"top":0.33439744,"width":0.020611702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.52377,"top":0.33439744,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.5305851,"top":0.33439744,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.5305851,"top":0.33439744,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.54737365,"top":0.33439744,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"bounds":{"left":0.5503657,"top":0.33439744,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"bounds":{"left":0.5503657,"top":0.33439744,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"7 comments","depth":12,"bounds":{"left":0.8384308,"top":0.3120511,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7","depth":13,"bounds":{"left":0.8450798,"top":0.31364724,"width":0.002493351,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Test hublets latency","depth":12,"bounds":{"left":0.45462102,"top":0.36352754,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Test hublets latency","depth":12,"bounds":{"left":0.47257313,"top":0.36312848,"width":0.05069814,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Test hublets latency","depth":13,"bounds":{"left":0.47257313,"top":0.36312848,"width":0.05069814,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 23 checks OK","depth":13,"bounds":{"left":0.52460104,"top":0.36113328,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11443 opened","depth":13,"bounds":{"left":0.47257313,"top":0.38467678,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Dec 8, 2025","depth":14,"bounds":{"left":0.50265956,"top":0.38467678,"width":0.028922873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.5315825,"top":0.38467678,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.5383976,"top":0.38467678,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.5383976,"top":0.38467678,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55518615,"top":0.38467678,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.5581782,"top":0.38467678,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.5581782,"top":0.38467678,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.36272946,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.3643256,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-19501 webhook based opportunity sync","depth":12,"bounds":{"left":0.45462102,"top":0.41380686,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-19501 webhook based opportunity sync","depth":12,"bounds":{"left":0.47257313,"top":0.41380686,"width":0.109375,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-19501 webhook based opportunity sync","depth":13,"bounds":{"left":0.47257313,"top":0.41380686,"width":0.109375,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.58327794,"top":0.4114126,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11327 opened","depth":13,"bounds":{"left":0.47257313,"top":0.43535516,"width":0.029753989,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Nov 10, 2025","depth":14,"bounds":{"left":0.50232714,"top":0.43535516,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.53291225,"top":0.43535516,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.5397274,"top":0.43535516,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.5397274,"top":0.43535516,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55651593,"top":0.43535516,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.55950797,"top":0.43535516,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.55950797,"top":0.43535516,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"9 comments","depth":12,"bounds":{"left":0.83826464,"top":0.41300878,"width":0.00930851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9","depth":13,"bounds":{"left":0.84474736,"top":0.41460496,"width":0.0028257978,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 18908 streaming on chat abort","depth":12,"bounds":{"left":0.45462102,"top":0.46448523,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 18908 streaming on chat abort","depth":12,"bounds":{"left":0.47257313,"top":0.46448523,"width":0.085605055,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 18908 streaming on chat abort","depth":13,"bounds":{"left":0.47257313,"top":0.46448523,"width":0.085605055,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 23 checks OK","depth":13,"bounds":{"left":0.55950797,"top":0.46209097,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11197 opened","depth":13,"bounds":{"left":0.47257313,"top":0.48603353,"width":0.029089095,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Oct 13, 2025","depth":14,"bounds":{"left":0.50166225,"top":0.48603353,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.53174865,"top":0.48603353,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53856385,"top":0.48603353,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53856385,"top":0.48603353,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55518615,"top":0.48603353,"width":0.0031582448,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.5583444,"top":0.48603353,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.5583444,"top":0.48603353,"width":0.009474734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.46368715,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.46528333,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-18750 debug logs for OD data loading","depth":12,"bounds":{"left":0.45462102,"top":0.5151636,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-18750 debug logs for OD data loading","depth":12,"bounds":{"left":0.47257313,"top":0.51476455,"width":0.104222074,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-18750 debug logs for OD data loading","depth":13,"bounds":{"left":0.47257313,"top":0.51476455,"width":0.104222074,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"24 / 25 checks OK","depth":13,"bounds":{"left":0.578125,"top":0.51276934,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11125 opened","depth":13,"bounds":{"left":0.47257313,"top":0.5363129,"width":0.02925532,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Sep 18, 2025","depth":14,"bounds":{"left":0.50182843,"top":0.5363129,"width":0.030585106,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.53241354,"top":0.5363129,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53922874,"top":0.5363129,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53922874,"top":0.5363129,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55585104,"top":0.5363129,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.5588431,"top":0.5363129,"width":0.009640957,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.5588431,"top":0.5363129,"width":0.009640957,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-17640 push data to Dynamics","depth":12,"bounds":{"left":0.45462102,"top":0.5654429,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-17640 push data to Dynamics","depth":12,"bounds":{"left":0.47257313,"top":0.5654429,"width":0.08361037,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-17640 push data to Dynamics","depth":13,"bounds":{"left":0.47257313,"top":0.5654429,"width":0.08361037,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.5575133,"top":0.56304866,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#10810 opened","depth":13,"bounds":{"left":0.47257313,"top":0.58699125,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Jun 19, 2025","depth":14,"bounds":{"left":0.50265956,"top":0.58699125,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.532746,"top":0.58699125,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53956115,"top":0.58699125,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53956115,"top":0.58699125,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.55634975,"top":0.58699125,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"bounds":{"left":0.5593417,"top":0.58699125,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"bounds":{"left":0.5593417,"top":0.58699125,"width":0.018118352,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.5646449,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.566241,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-13692 add after parameter to opportunity sync for HS","depth":12,"bounds":{"left":0.45462102,"top":0.6161213,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-13692 add after parameter to opportunity sync for HS","depth":12,"bounds":{"left":0.47257313,"top":0.61572224,"width":0.14478059,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-13692 add after parameter to opportunity sync for HS","depth":13,"bounds":{"left":0.47257313,"top":0.61572224,"width":0.14478059,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#9246 opened","depth":13,"bounds":{"left":0.47257313,"top":0.63727057,"width":0.028756648,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Jul 9, 2024","depth":14,"bounds":{"left":0.5013298,"top":0.63727057,"width":0.026928192,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.52825797,"top":0.63727057,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.53507316,"top":0.63727057,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.53507316,"top":0.63727057,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.5518617,"top":0.63727057,"width":0.0029920214,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.55485374,"top":0.63727057,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.55485374,"top":0.63727057,"width":0.030086435,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.83892953,"top":0.61532325,"width":0.008643617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.84557843,"top":0.6169194,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ProTip!","depth":11,"bounds":{"left":0.5806183,"top":0.6847566,"width":0.015791224,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"What’s not been updated in a month:","depth":10,"bounds":{"left":0.59640956,"top":0.6847566,"width":0.08211436,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"updated:<2026-04-15","depth":10,"bounds":{"left":0.67852396,"top":0.6847566,"width":0.048204787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-6086964218744423060
|
6641796714389788430
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:open is:pr author:LakyLak
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
23 / 23 checks OK
#12066 opened
4 days ago
by
LakyLak
LakyLak
•
1 review approval
Approved
7 comments
7
Test hublets latency
Test hublets latency
Test hublets latency
22 / 23 checks OK
#11443 opened
on Dec 8, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
11 / 12 checks OK
#11327 opened
on Nov 10, 2025
by
LakyLak
LakyLak
•
Draft
Draft
9 comments
9
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
22 / 23 checks OK
#11197 opened
on Oct 13, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
24 / 25 checks OK
#11125 opened
on Sep 18, 2025
by
LakyLak
LakyLak
•
Draft
Draft
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
11 / 12 checks OK
#10810 opened
on Jun 19, 2025
by
LakyLak
LakyLak
•
1 review approval
Approved
1 comment
1
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
#9246 opened
on Jul 9, 2024
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
ProTip!
What’s not been updated in a month:
updated:<2026-04-15...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47806
|
1698
|
27
|
2026-05-15T08:53:27.399938+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835207399_m1.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls/LakyLak
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:open is:pr author:LakyLak
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
23 / 23 checks OK
#12066 opened
4 days ago
by
LakyLak
LakyLak
•
1 review approval
Approved
7 comments
7
Test hublets latency
Test hublets latency
Test hublets latency
22 / 23 checks OK
#11443 opened
on Dec 8, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
11 / 12 checks OK
#11327 opened
on Nov 10, 2025
by
LakyLak
LakyLak
•
Draft
Draft
9 comments
9
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
22 / 23 checks OK
#11197 opened
on Oct 13, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
24 / 25 checks OK
#11125 opened
on Sep 18, 2025
by
LakyLak
LakyLak
•
Draft
Draft
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
11 / 12 checks OK
#10810 opened
on Jun 19, 2025
by
LakyLak
LakyLak
•
1 review approval
Approved
1 comment
1
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
#9246 opened
on Jul 9, 2024
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
ProTip!
What’s not been updated in a month:
updated:<2026-04-15
updated:<2026-04-15
.
Footer
Footer
GitHub Homepage
© 2026 GitHub, Inc....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"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,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"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":"Filters","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:open is:pr author:LakyLak","depth":11,"on_screen":true,"value":"is:open is:pr author:LakyLak","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Clear current search query, filters, and sorts","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Clear current search query, filters, and sorts","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"7 Open","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 Open","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"359 Closed","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"359 Closed","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"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":"Author","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"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":"Label","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","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":"Projects","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","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":"Milestones","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","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":"Reviews","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"on_screen":true,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"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":"Sort","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20725 add HS rate limit handling on activities rematching","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20725 add HS rate limit handling on activities rematching","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"23 / 23 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12066 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"7 comments","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Test hublets latency","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Test hublets latency","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Test hublets latency","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 23 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11443 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Dec 8, 2025","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-19501 webhook based opportunity sync","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-19501 webhook based opportunity sync","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-19501 webhook based opportunity sync","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11327 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Nov 10, 2025","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"9 comments","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 18908 streaming on chat abort","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 18908 streaming on chat abort","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 18908 streaming on chat abort","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 23 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11197 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Oct 13, 2025","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-18750 debug logs for OD data loading","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-18750 debug logs for OD data loading","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-18750 debug logs for OD data loading","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"24 / 25 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11125 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Sep 18, 2025","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-17640 push data to Dynamics","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-17640 push data to Dynamics","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-17640 push data to Dynamics","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#10810 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Jun 19, 2025","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-13692 add after parameter to opportunity sync for HS","depth":12,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-13692 add after parameter to opportunity sync for HS","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-13692 add after parameter to opportunity sync for HS","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#9246 opened","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Jul 9, 2024","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ProTip!","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"What’s not been updated in a month:","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"updated:<2026-04-15","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"updated:<2026-04-15","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Footer","depth":7,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Footer","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub Homepage","depth":7,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"© 2026 GitHub, Inc.","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
177958422462239149
|
5488885105925281550
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:open is:pr author:LakyLak
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
JY-20725 add HS rate limit handling on activities rematching
23 / 23 checks OK
#12066 opened
4 days ago
by
LakyLak
LakyLak
•
1 review approval
Approved
7 comments
7
Test hublets latency
Test hublets latency
Test hublets latency
22 / 23 checks OK
#11443 opened
on Dec 8, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
JY-19501 webhook based opportunity sync
11 / 12 checks OK
#11327 opened
on Nov 10, 2025
by
LakyLak
LakyLak
•
Draft
Draft
9 comments
9
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
Jy 18908 streaming on chat abort
22 / 23 checks OK
#11197 opened
on Oct 13, 2025
by
LakyLak
LakyLak
•
Draft
Draft
1 comment
1
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
JY-18750 debug logs for OD data loading
24 / 25 checks OK
#11125 opened
on Sep 18, 2025
by
LakyLak
LakyLak
•
Draft
Draft
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
JY-17640 push data to Dynamics
11 / 12 checks OK
#10810 opened
on Jun 19, 2025
by
LakyLak
LakyLak
•
1 review approval
Approved
1 comment
1
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
JY-13692 add after parameter to opportunity sync for HS
#9246 opened
on Jul 9, 2024
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
ProTip!
What’s not been updated in a month:
updated:<2026-04-15
updated:<2026-04-15
.
Footer
Footer
GitHub Homepage
© 2026 GitHub, Inc....
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47808
|
1698
|
28
|
2026-05-15T08:53:38.963445+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835218963_m1.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8043719072324535154
|
-8628527368849355612
|
app_switch
|
hybrid
|
NULL
|
Project: faVsco.js, menu
PhpStormFileEditViewNavig Project: faVsco.js, menu
PhpStormFileEditViewNavigateCodeLaravelRefactorRunToolsGitWindowHelpscreenpipe"-zsh₴4DOCKERO ₴1DEV (-zsh)82APP (-zsh)X3whisper_init_state:kv crosssize =9.44 MBwhisper_init_state:kv padsize2.36 MBwhisper_init_state:compute buffer (conv)=whisper_init_state:computebuffer (encode) =whisper_init_state:compute buffer (cross)whisper_init_state:computebuffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu:device 0: Metal (type:1)whisper_backend_init_gpu:found GPU device 0: Metal (type: 1, cnt:0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init:founddevice:Apple M1ggml_metal_init:pickingdefault device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrency= trueggml_metal_init: use graph optimize=truewhisper_backend_init: using BLAS backendwhisper_init_state: kv selfsize3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type:1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init: use concurrency= trueggml_metal_init: use graph optimize= truewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size=3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15111:53:17.6375522screenpipe"885INFO screenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunksJiminny Tech Day • 6h 7 m leftAec2-user@ip-10-20-...₴6ec2-user@ip-10-30-...100% [8•Fri 15 May 11:53:38181ec2-user@ip-10-...• *8...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47809
|
1699
|
40
|
2026-05-15T08:53:39.012386+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835219012_m2.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.15259309,"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":"JY-20891-improve-sms-text-relays, menu","depth":5,"bounds":{"left":0.19115691,"top":0.019952115,"width":0.0944149,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20891-improve-sms-text-relays<br/>109 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8078458,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8231383,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.91522604,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9265292,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9378325,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96575797,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.97706115,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.98836434,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7581618884890279806
|
-8204352174202572862
|
app_switch
|
hybrid
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
ActivityFllesPhpStormViewINavicareCodeLaravelKeractorJiminny...vXstarred• jiminny-x-integrati..8 platform-inner-team® Channels# ai-chapter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofa-office# support# thank-yous# the people of fimi..? Direct messages8P. Stoyan TomovQ. Galya Dimitrova EP. Aneliya Angelovaa Vasil Vasilev#reMessag) CircDepProlag;Messag+ AaTOOISWindowmelprtavsco.s%9 JY-20891-improve-sms-text-relaysProject© InviteUserToTeamAction.php© CrmActivityService.phpM+ WEBHOOK FILTERING MPLEMENTATIспескалокешукеmоtемatch.php© RematchActivityOnCrmObjectDetach.phpih External Librariesv = Scratches and ConsolesDatabase Consoles© Activity.php x] © UpdateCrmData.phpV dEUA console (EU]4 DEAL RISKS [EU]cLass Activity extends Model implements665A4 A169 X 4 X 102 1,4 A Y666oublic tunction uodate ctvrvermbatalarrav srecords): vordiA DI [EU]A EU [EU]v A jiminny@localhost2121A console (jiminny@localhost]if ($this-›stage_id === null && $stage) {$this-›stage_id = $stage->id;& Ul Uiminny@localnostA HS_local [jiminny@localhost]21232124A SF [iiminny@localhost)1 zoho_dev [jiminny@localhost]V & PROD2127if ($opportunity && $this->opportunity_id |== $opportunity->id) {$this->opportunity_id = $opportunity->id;console PROD≥670=6736741=676A console_1 [PROD]& DIIPROD.if ($opportunity && $this->value !== $opportunity->value) {sunis->value = sopporcunity-›valueDLФA> AQAIV APA PROD¿ console PA PRODI¿ console 1IPA PRODIIA console 2 PA PRODI console 3 leA PRODI console 4 l0AI PRODd console 5 laAI PRODIIA console_6 [QAI PROD] =678// Always set contact_id when available, regardless of account_id statuif ($this->contact_id === null && $contact) {$this->contact_id = $contact->id;584 MA console 7 lGAI PRODIIothas->saveo7 elseif ($strategy == UpdateCrnDataByStrategy:: Account && Sthis->account_io-Also uodate the parent activity if reauired.checking we don't creatSthis-slead id = null:E custom.log( scratch_8.jsonE laravel.logA console [PROD] x A console [EU)Hi accounte (Ctlll© FixActivitiesOpportunity.php1 console_7 [QAI PROD]4 SF [jiminny@localhost]A HS_local [jiminny@localhost]f stages (EU]iii teams (EU]ImporntbotkecoraingJoo.phpA console (STAGING)Tx: Auto vPlaygroundde jiminnyROM automated_report_results WHERE uvid_to_bin('822fa41b-afd3-43a9-a248-86b0e3, m040 A1 A40 M65 A VServices# OutputunD iminny.text relays XTx,y M DatahaceV AEUteamsl accountsstagesconsole~A jiminny@localhostA HS localA SFV A PROD« console 1S 414 msV A OAI PRODdconsole7> ASTAGING* Dockerid YMstatus Y32416 orocessed32415 processed32208 processed32207 processed30614 processed30613 processed30501 nrocessedI code YDDLQmsender Y<nul> Stovan_Tomov <stovan.tomovdiiminnv.com›<null> Mario Georgiev ‹[EMAIL]><null> Mario Georgiev <[EMAIL]>‹null> Mario Georgiev <[EMAIL]>‹null> Mario Georgiev <[EMAIL]><null> Mario Georgiev <[EMAIL]><null> Mario Georgiev <[EMAIL]>rom text_relays where created_at > '2026-05-01'(32415, 32416);024141rom users where team_id = 2 and email like "%scott%' and id = 29510;ROM activities WHERE uvid_to_bin('67cebfc2-ed56-44a2-8C68-7a0286ed8618') = uuid; # 79763436il_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuseslprovider 1d IN C'1922027868a64042', '19e2033ed8ea6b10'01status. telerhony provider_ 1d. created_atN80028719. 80828846)1status, code, emall sent at, created at. undated at.relavsrelayser LIKE'%mario georgiev%' OR sender LIKE I%stovan.tomov%reated_at DESCI recipient YMario Georgiev <447893937879.447577084583.4060XDw92Zdtxt.Timinnv.com›[EMAIL] Georgiev <[EMAIL]›Mario Georgiev <[EMAIL]›Mario Georgiev <[EMAIL]›Mario Georgiev <[EMAIL]>Mario Georgiev <[EMAIL]›Jiminny lech Day • on /mlen100% 1528• Fri 15 May 11:53:38wenwaeReview PR for ActivityDebua Text Relay Fa+0...nore information. duotina reterence 06261416-2786-4d8c-9118Thought for 1s>Perfect! The email shows:Reference: 0626141c-27a6-4d8c-aff8-7c8020a2c656• Code: 2200Code 2200 is REASON CODE SENDER MTSMATCH line 35 in EmailTextRelav.oho), which means"Sender does not match the origin activity."This is a different text_relay record than the one we've been looking at (32416 has UUID Bx4CD18652A4D7AA2DA5268705E3B21366 . Let me tind the record with UUID 0626141с-27аб-4d8c-aff8-7c80• salSELECT id, uuid, status, code, sender, recipient, created_at, updated_atFROM text relavsWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');This will show the actual failed text_relay record that triggered the failure email Stoyan received.Diving.A Ourincluded wekly usage quota is exhausted. Using your extra usage. Quota resets May 17, 1:00 AMAsk anything (3AL)+ <> CodeSWE-1.6CSVvd1+08I created_at Y2026-05-13 07:20:092026-05-13 07-10-322025-10-17 11:15:032025-10-17 11:10:042024-05-24 11:10:022024-05-24 11:05:022024-04-23 09:05:02W Windsurf Teams 688:10 UTF-8 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47811
|
1699
|
41
|
2026-05-15T08:53:50.688200+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835230688_m2.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.15259309,"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":"JY-20891-improve-sms-text-relays, menu","depth":5,"bounds":{"left":0.19115691,"top":0.019952115,"width":0.0944149,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20891-improve-sms-text-relays<br/>109 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8078458,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8231383,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.91522604,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9265292,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9378325,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96575797,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.97706115,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.98836434,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-4559205040332170341
|
-8132287983094879294
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
ActivityFllesLaterPhpStormViewINavicareCodeLaravelKeractorTOOISWindowmelpFV favsco.js v°9 JY-20891-improve-sms-text-relays k vJiminny...vsStarre• jiminny-x-integrati…..8 platform-inner-teamProject© InviteUserToTeamAction.php© CrmActivityService.php#reM+ WEBHOOK FILTERING MPLEMENTATIспескалокешукеmоtемatch.php© RematchActivityOnCrmObjectDetach.phpih External LibrariesMessagv = Scratches and ConsolesDatabase Consoles© Activity.php x] © UpdateCrmData.phpV dEU® Channels# ai-chapter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofa-office# support# thank-yous# the people of fimi..A console (EU]) Circ4 DEAL RISKS [EU]cLass Activity extends Model implements665A4 A169 X 4 X 102 1,4 A Y666• DerA DI [EU]oublic tunction uodate ctvrvermbatalarrav srecords): vordiProA EU [EU]v A jiminny@localhostif ($this-›stage_id === null && $stage) {A console (jiminny@localhost]2123$this-›stage_id = $stage->id;& Ul Uiminny@localnost≥670lag;A HS_local [jiminny@localhost]2124VieA SF [iiminny@localhost)1 zoho_dev [jiminny@localhost]if ($opportunity && $this->opportunity_id |== $opportunity->id) {=673V & PROD2127$this->opportunity_id = $opportunity->id;6741console PROD=676A console_1 [PROD]& DIIPROD.2131if ($opportunity && $this->value !== $opportunity->value) {sunis->value = sopporcunity-›valueDLФA=678> AQAIV APA PROD2133¿ console PA PRODI2135// Always set contact_id when available, regardless of account_id statu¿ console 1IPA PRODII2136if ($this->contact_id === null && $contact) {A console 2 PA PROD2137$this->contact_id = $contact->id;584 MI console 3 leA PROD2138I console 4 l0AI PROD12159othas->saveod console 5 laAI PRODII• Direct messages2140A console_6 [QAI PROD]7 elseif ($strategy == UpdateCrnDataByStrategy:: Account && Sthis->account_id2141Also uodate the parent activity if reauired.ichecking we don't creatA console 7 lGAI PRODII8P. Stoyan TomovSthis-slead id = null:Q. Galya Dimitrova EP. Aneliya AngelovaMessag# OutputunD iminny.text relays XTx,a Vasil Vasilev+ AaE custom.log( scratch_8.jsonE laravel.log4 SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD] x A console (EU)Hi accounte (Ctlllf stages (EU]iii teams (EU]© ImportBotRecordingJob.php© FixActivitiesOpportunity.php1 console_7 [QAI PROD]A console (STAGING)Tx: Auto vPlaygroundde jiminnyROM automated_report_results WHERE uvid_to_bin('822fa41b-afd3-43a9-a248-86b0e3i mg040 A1 A40 M65 A VServices+,o,cy M DatahaceV AEUteamsl accountsstagesconsole~A jiminny@localhostA HS localA SFV A PROD« console 1S 414 msV A OAI PRODdconsole7> ASTAGING* Dockerid YMstatus Y32416 orocessed32415 processed32208 processed32207 processed30614 processed30613 processed30501 nrocessedI code YDDLmsenderY<nul> Stovan_Tomov <stovan.tomovdiiminnv.com›<null> Mario Georgiev ‹[EMAIL]›<null> Mario Georgiev <[EMAIL]>‹null> Mario Georgiev <[EMAIL]>‹null> Mario Georgiev <[EMAIL]><null> Mario Georgiev <[EMAIL]><null> Mario Georgiev <[EMAIL]>Choskod aut IV.20901.imnravo-eme.tovt-rolaue /22 minutoc sndlrom text_relays where created_at > '2026-05-01'(32415, 32416);024141rom users where team_id = 2 and email like "%scott%' and id = 29510;ROM activities WHERE uvid_to_bin('67cebfc2-ed56-44a2-8C68-7a0286ed8618') = uuid; # 79763436il_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuseslprovider 1d IN C'1922027868a64042', '19e2033ed8ea6b10'01status. telerhony provider_ 1d. created_atN80028719. 80828846)1status, code, emall sent at, created at. undated at.relavsrelayser LIKE'%mario georgiev%' OR sender LIKE I%stovan.tomov%reated_at DESCI recipient YMario Georgiev <447893937879.447577084583.4060XDw92Zdtxt.Timinnv.com›[EMAIL] Georgiev <[EMAIL]>Mario Georgiev <[EMAIL]›Mario Georgiev <[EMAIL]›Mario Georgiev <[EMAIL]>Mario Georgiev <[EMAIL]›Jiminny lech Day • on / m lert100% 528• Fri 15 May 11:53:50wenwaeReview PR tor Activity• Debug Text Relay Fa+0...Please contact support for more information, quoting reference 0626141c-27a6-4d8c-aff8couzuazcbob and code 2200Periect. The email shows:• Reference: 0626141c-27a6-4d8c-aff8-7c8020a2c656Code: 2200Code 2200 is REASON_CODE_SENDER _MISMATCH (line 35 in EmailTextRelay.php), which means"Sender does not match the oriain activitv."This is a different text _relay record than the one we've been looking at (32416 has UUID ®x4CD18652A4D7AA2DA5268705E3B21366 ). Let me find the record with UUID 0626141c-27а6-4d8c-aff8-7c80• saSELECT id, uuid, status, code, sender, recipient, created at, updated atthom text_reldysuuid = uuid to bin 0626141c-27aб-4d8c-at18-7c8020a2c656')=This will show the actual talled text relav record that triagered the tallure emall Stovan received.ull ...Ourincluded weekly usage quota is exhausted. Using your extra usage. Quota resets May 17,11:00 AMAsk anything (3AL)+ <> CodeSWE-1.6•:-CSVvmcreated at Y2026-05-13 07:20:092026-05-13 07-10-322025-10-17 11:15:032025-10-17 11:10:042024-05-24 11:10:022024-05-24 11:05:022024-04-23 09:05:02W Windsurf Teams 688:10 UTF-84 spaces...
|
47809
|
NULL
|
NULL
|
NULL
|
|
47810
|
1698
|
29
|
2026-05-15T08:53:50.688214+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835230688_m1.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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...
|
[{"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":"JY-20891-improve-sms-text-relays, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20891-improve-sms-text-relays<br/>109 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-4559205040332170341
|
-8132287983094879294
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
PhpStormFileEditViewNavigateCodeLaravelRefactorRunToolsGitWindowHelpscreenpipe"-zsh₴4DOCKERO ₴1DEV (-zsh)82APP (-zsh)X3whisper_init_state:kv crosssize =9.44 MBwhisper_init_state:kv padsize2.36 MBwhisper_init_state:compute buffer (conv)whisper_init_state:computebuffer (encode) =whisper_init_state:compute buffer (cross)whisper_init_state:computebuffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu:device 0: Metal (type:1)whisper_backend_init_gpu:found GPU device 0: Metal (type: 1, cnt:0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init:founddevice:Apple M1ggml_metal_init:pickingdefault device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrency= trueggml_metal_init: use graph optimize=truewhisper_backend_init: using BLAS backendwhisper_init_state: kv selfsize3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type:1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init: use concurrency= trueggml_metal_init: use graph optimize= truewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size=3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15111:53:17.6375522screenpipe"885INFO screenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunksJiminny Tech Day • 6h 7 m leftAec2-user@ip-10-20-...₴6ec2-user@ip-10-30-...100% [8•Fri 15 May 11:53:50181ec2-user@ip-10-...• *8...
|
47808
|
NULL
|
NULL
|
NULL
|
|
47812
|
1699
|
42
|
2026-05-15T08:53:53.161124+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835233161_m2.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.15259309,"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":"JY-20891-improve-sms-text-relays, menu","depth":5,"bounds":{"left":0.19115691,"top":0.019952115,"width":0.0944149,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20891-improve-sms-text-relays<br/>109 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8078458,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8231383,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.91522604,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9265292,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9378325,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96575797,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.97706115,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.98836434,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.4162234,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"169","depth":4,"bounds":{"left":0.4261968,"top":0.17478053,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.4401596,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"102","depth":4,"bounds":{"left":0.45013297,"top":0.17478053,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.46409574,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.4737367,"top":0.17318435,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.48105052,"top":0.17318435,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.48969415,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.49833778,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.5093085,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.51795214,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.5265958,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.5375665,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.54853725,"top":0.123703115,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.57513297,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.58610374,"top":0.123703115,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7569814,"top":0.123703115,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.72639626,"top":0.14844373,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.7386968,"top":0.14844373,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.74800533,"top":0.14844373,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"65","depth":4,"bounds":{"left":0.7603058,"top":0.14844373,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.77227396,"top":0.14684756,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.77958775,"top":0.14684756,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01'\nand id IN (32415, 32416);\n# and id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01'\nand id IN (32415, 32416);\n# and id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.13863032,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8724424516320409755
|
8179532969745786684
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47813
|
1698
|
30
|
2026-05-15T08:54:01.475343+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835241475_m1.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
[{"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":"JY-20891-improve-sms-text-relays, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20891-improve-sms-text-relays<br/>109 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"169","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"102","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"65","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":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01'\nand id IN (32415, 32416);\n# and id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01'\nand id IN (32415, 32416);\n# and id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;","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":false,"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":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand All","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":"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":false,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8724424516320409755
|
8179532969745786684
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47815
|
1699
|
43
|
2026-05-15T08:54:03.318491+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835243318_m2.jpg...
|
iTerm2
|
screenpipe"
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
ActivitFllesPhpStormViewINavicareCodeLaravelKeract ActivitFllesPhpStormViewINavicareCodeLaravelKeractorloolsWindowmelpJiminny...vXstarred• jiminny-x-integrati..8 platform-inner-teamE) Channelsic al-chaoter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# general#jiminny-bg# platform-tickets# product_launches# random# releases# sofa-office# support# thank-yous# the people of fimi..o- Direct messagesStovan Tomov• Galva Dimitrova De Aneliva Angelovaa Vasil VasilevFV faVsco.js?9 JY-20891-improve-sms-text-relays k#reMessagProjectv© InviteUserToTeamAction.php(c) CrmActivityService.ongM+ WEBHOOK FILTERING MPLEMENTATIспескалокешукеmоtемatch.php@ RematchActivityOnCrmObjectDetach.phpih External Liorariesv = Scratches and Consoles•Cird•DerProlag;MessagAa• Database ConsolesVAEU« console [EU]A DEAL RISKS (EU]A DI (EU]A EU (EU]v A jiminny@localhostA console [jiminny@localhost& Ul Uiminny@localnostA no local liminny alocalnostA SF [iiminny@localhost)A zoho dev [jiminny@localhost]• & PRODconsole PROD& console 1 [PROD]& DIIPROD.DLФA> ₫OAiV APA PROD¿ console PA PRODI© Activity.php x| © UpdateCrmData.phpclass Activity extends Model implementsoublic tunction uodate ctvrvermbatalarrav srecords): vo1di64 A169 ×4 ×102 14 ^ V 648212312124212721312133¿ console 1IPA PRODIIA console 2 PA PRODI console 3 leA PROD215521362137I console 4 l0AI PRODd console 5 laAI PRODIIA console 6 loAI PRODIA console 7 lGAI PRODIIASTAGING#concole [STAGING121592140214121492143A concole 1 ICTACINGI& uranus [STAGINGI>D Extensionsv MScratchesEphpstorm_shortcuts.txt3 ccratch tytt scratch_1.jsonccratch 2,isonf° scratch 3.isonscratch_4 txtpig scratch_5.php09 scratch_6.phpf" scratch._7.isonf" scratch_8.ison4° stage2.isonE° test<° test.htmllphe tmo.oho21492146215112152|2157|2154if (this->stage 1d === null && Sstage) <$this->stage_id = $stage->id;if (Sopportunity && Sthis->opportunity_id |== $opportunity->id) {$this->opportunity_id = Sopportunity->id;if (Sopportunity && Sthis->value !== Sopportunity->value) {— 050— 657658659sunis->value = sopporcunity-›value— 661662|// Always set contact id when available, regardless of account id statusif (Sthis->contact id === null && Scontact) {Sthis->contact id = Scontact->id:=667othas->saveo} elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id = 676Also uodate the parent activity if reauired.checking we don't creates$this->lead_id = null;if (Sthis->stage && Sthis->stage-›qetTvne() === Stage::TYPE LEAD) {sthis->stage 1d = nullI undate the account and onnontunito on the setivito necond ie enceibl eSthis->account id= Saccount->id.if (Sthis->stage_id === null && $stage) {Sthis->staae id = Sstage->id»=678E679=680681684if ($this->opportunity id === null && Sopportunity) {$this->opportunity id = Sopportunity->id;c+hic->value = Sooportunity->value,=684 vSthis->saveO:Choskod aut IV.20901.imnravo-eme.tovt-rolaue /22 minutoc snd=custom.logt scratch_8.json= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]A console [PROD] X A console [EU]fiò accounts [EU]tii stages (EU]iiò teams ([EU]ImporbotkecoraingJoo.onp© FixActivitiesOpportunity.php• console_/ QAI PRODA console [STAGING)Tx: Autodo jiminnyroul accounts wuere coi cont tuuragont oo a 1y0000040 A1 A40 M65 A Vrom automated_report_results where id = 1976;rom automated_reports where id = 583;rom activity_searches where id = 87714;rom activity_search_filters where activity_search_id = 87714;ROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;ROM crm_configurations WHERE provider = 'hubspot';ron race_timits,automated report results where media type = 'pdf' and status = 218, 1812)1where 1d = 54;ROM users WHERE id IN (24623,29443,29613):ROM automated report results WHERE uuid to bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid:|rom text relavs where created at > "2026-05-01°(32415. 32416)324121rom users where team id = 2 and email like '%scottg' and id = 29510:RoM activities WhERE uuld to bin67cehfc2-ed56-4422-8668-1a0286ed8618") = Uuid: # 19163456oroviden id. COUNT*) as count. GROUP CONCATGid as ids. GROUP CONCATistatus) as statusesrelaysIl oroviden id TN119e2027868a64h421119e2033ed8ea6b10')|mail nnoviden id.ctatuc telenhonv nnoviden id copated atitiesIN (RA029710 RAADRRLA)•status, code, email sent at, created at, updated atnplaySN (32415, 32416):code, sender, recipient, created atrelayser LIKE '%mario.georgiev%' OR sender LIKE '%stovan.tomov%rearedar Uesu• Jiminny lech Day • on om len100% 2• Fri 15 May 11:54:03AskJiminnyReview PR tor ActivityDebug Text Relay Fal+0...could you veriry the exact emall they receivea: soecirically:1. Does the emall rerea text relay ID it should say "quoting reterence ia and code{code}")?<. What code is mentioned in the emall:3. Is it definitely the "We're really sorry but we could not send your text message" email, orcould it be a different notification?This will helo determine it they received the SmsRelavsalled email or a ditterent notiication withisimilar wordingFrom: The Jiminny Team <[EMAIL]>Subie wt: do ur ty x3, esza ge failed to sendH6stoyan.tomovejiminny.comswere oaly duey butwmessia n otein doo ur tex message.Peooogast unpo de 20 hfrmatin, qutig oftrne 06281416 2738- 4a8e ate-Thought for 1clPerfect! The email shows:• Reference: 0626141c-27a6-4d8c-af48_7c8020a2c656• Code: 2200Code 2200 is REASON CODE SENDER MISMATCH line 35 in EmailTextRelav.oho), which means"Sender does not match the origin activity."This is a different text_relay record than the one we've been looking at (32416 has UUID 0x4CD18652A4D7AA2DA5268705E3B21366 . Let me tind the record with UUID 0626141c-27a6-4d8c-aff8-7c80• saSELECT id, uuid, status, code, sender, recipient, created at, updated atFROM text relaysWHERE uuid = uuid to bin('0626141c-27a6-4d8c-aff8-7c8020a2c656'):This will show the actual failed text relay record that triggered the failure email Stoyan received.nl "Your included weekly usage quota is exhausted. Using your extra usage. Quota resets May 17, 11:00 AMAsk anvthina (*4L÷ es CodolSWE.1GW Windsurf Teams 688:10 UTF-84 spaces...
|
NULL
|
-8316539827783343427
|
NULL
|
click
|
ocr
|
NULL
|
ActivitFllesPhpStormViewINavicareCodeLaravelKeract ActivitFllesPhpStormViewINavicareCodeLaravelKeractorloolsWindowmelpJiminny...vXstarred• jiminny-x-integrati..8 platform-inner-teamE) Channelsic al-chaoter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# general#jiminny-bg# platform-tickets# product_launches# random# releases# sofa-office# support# thank-yous# the people of fimi..o- Direct messagesStovan Tomov• Galva Dimitrova De Aneliva Angelovaa Vasil VasilevFV faVsco.js?9 JY-20891-improve-sms-text-relays k#reMessagProjectv© InviteUserToTeamAction.php(c) CrmActivityService.ongM+ WEBHOOK FILTERING MPLEMENTATIспескалокешукеmоtемatch.php@ RematchActivityOnCrmObjectDetach.phpih External Liorariesv = Scratches and Consoles•Cird•DerProlag;MessagAa• Database ConsolesVAEU« console [EU]A DEAL RISKS (EU]A DI (EU]A EU (EU]v A jiminny@localhostA console [jiminny@localhost& Ul Uiminny@localnostA no local liminny alocalnostA SF [iiminny@localhost)A zoho dev [jiminny@localhost]• & PRODconsole PROD& console 1 [PROD]& DIIPROD.DLФA> ₫OAiV APA PROD¿ console PA PRODI© Activity.php x| © UpdateCrmData.phpclass Activity extends Model implementsoublic tunction uodate ctvrvermbatalarrav srecords): vo1di64 A169 ×4 ×102 14 ^ V 648212312124212721312133¿ console 1IPA PRODIIA console 2 PA PRODI console 3 leA PROD215521362137I console 4 l0AI PRODd console 5 laAI PRODIIA console 6 loAI PRODIA console 7 lGAI PRODIIASTAGING#concole [STAGING121592140214121492143A concole 1 ICTACINGI& uranus [STAGINGI>D Extensionsv MScratchesEphpstorm_shortcuts.txt3 ccratch tytt scratch_1.jsonccratch 2,isonf° scratch 3.isonscratch_4 txtpig scratch_5.php09 scratch_6.phpf" scratch._7.isonf" scratch_8.ison4° stage2.isonE° test<° test.htmllphe tmo.oho21492146215112152|2157|2154if (this->stage 1d === null && Sstage) <$this->stage_id = $stage->id;if (Sopportunity && Sthis->opportunity_id |== $opportunity->id) {$this->opportunity_id = Sopportunity->id;if (Sopportunity && Sthis->value !== Sopportunity->value) {— 050— 657658659sunis->value = sopporcunity-›value— 661662|// Always set contact id when available, regardless of account id statusif (Sthis->contact id === null && Scontact) {Sthis->contact id = Scontact->id:=667othas->saveo} elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id = 676Also uodate the parent activity if reauired.checking we don't creates$this->lead_id = null;if (Sthis->stage && Sthis->stage-›qetTvne() === Stage::TYPE LEAD) {sthis->stage 1d = nullI undate the account and onnontunito on the setivito necond ie enceibl eSthis->account id= Saccount->id.if (Sthis->stage_id === null && $stage) {Sthis->staae id = Sstage->id»=678E679=680681684if ($this->opportunity id === null && Sopportunity) {$this->opportunity id = Sopportunity->id;c+hic->value = Sooportunity->value,=684 vSthis->saveO:Choskod aut IV.20901.imnravo-eme.tovt-rolaue /22 minutoc snd=custom.logt scratch_8.json= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]A console [PROD] X A console [EU]fiò accounts [EU]tii stages (EU]iiò teams ([EU]ImporbotkecoraingJoo.onp© FixActivitiesOpportunity.php• console_/ QAI PRODA console [STAGING)Tx: Autodo jiminnyroul accounts wuere coi cont tuuragont oo a 1y0000040 A1 A40 M65 A Vrom automated_report_results where id = 1976;rom automated_reports where id = 583;rom activity_searches where id = 87714;rom activity_search_filters where activity_search_id = 87714;ROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;ROM crm_configurations WHERE provider = 'hubspot';ron race_timits,automated report results where media type = 'pdf' and status = 218, 1812)1where 1d = 54;ROM users WHERE id IN (24623,29443,29613):ROM automated report results WHERE uuid to bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid:|rom text relavs where created at > "2026-05-01°(32415. 32416)324121rom users where team id = 2 and email like '%scottg' and id = 29510:RoM activities WhERE uuld to bin67cehfc2-ed56-4422-8668-1a0286ed8618") = Uuid: # 19163456oroviden id. COUNT*) as count. GROUP CONCATGid as ids. GROUP CONCATistatus) as statusesrelaysIl oroviden id TN119e2027868a64h421119e2033ed8ea6b10')|mail nnoviden id.ctatuc telenhonv nnoviden id copated atitiesIN (RA029710 RAADRRLA)•status, code, email sent at, created at, updated atnplaySN (32415, 32416):code, sender, recipient, created atrelayser LIKE '%mario.georgiev%' OR sender LIKE '%stovan.tomov%rearedar Uesu• Jiminny lech Day • on om len100% 2• Fri 15 May 11:54:03AskJiminnyReview PR tor ActivityDebug Text Relay Fal+0...could you veriry the exact emall they receivea: soecirically:1. Does the emall rerea text relay ID it should say "quoting reterence ia and code{code}")?<. What code is mentioned in the emall:3. Is it definitely the "We're really sorry but we could not send your text message" email, orcould it be a different notification?This will helo determine it they received the SmsRelavsalled email or a ditterent notiication withisimilar wordingFrom: The Jiminny Team <[EMAIL]>Subie wt: do ur ty x3, esza ge failed to sendH6stoyan.tomovejiminny.comswere oaly duey butwmessia n otein doo ur tex message.Peooogast unpo de 20 hfrmatin, qutig oftrne 06281416 2738- 4a8e ate-Thought for 1clPerfect! The email shows:• Reference: 0626141c-27a6-4d8c-af48_7c8020a2c656• Code: 2200Code 2200 is REASON CODE SENDER MISMATCH line 35 in EmailTextRelav.oho), which means"Sender does not match the origin activity."This is a different text_relay record than the one we've been looking at (32416 has UUID 0x4CD18652A4D7AA2DA5268705E3B21366 . Let me tind the record with UUID 0626141c-27a6-4d8c-aff8-7c80• saSELECT id, uuid, status, code, sender, recipient, created at, updated atFROM text relaysWHERE uuid = uuid to bin('0626141c-27a6-4d8c-aff8-7c8020a2c656'):This will show the actual failed text relay record that triggered the failure email Stoyan received.nl "Your included weekly usage quota is exhausted. Using your extra usage. Quota resets May 17, 11:00 AMAsk anvthina (*4L÷ es CodolSWE.1GW Windsurf Teams 688:10 UTF-84 spaces...
|
47812
|
NULL
|
NULL
|
NULL
|
|
47814
|
1698
|
31
|
2026-05-15T08:54:03.320777+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835243320_m1.jpg...
|
iTerm2
|
screenpipe"
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorRun PhpStormFileEditViewNavigateCodeLaravelRefactorRunToolsGitWindowHelpscreenpipe"₴4(iho]Jiminny Tech Day • 6h 6 m leftADOCKERO ₴1DEV (-zsh)82APP (-zsh)*3-zshscreenpipe*885ec2-user@ip-10-20-...886-ec2-user@ip-10-30-...whisper_init_state:whisper_init_state:kv padsize2.36 MBcompute buffer (conv)whisper_init_state: computebuffer (encode) =whisper_init_state:compute buffer (cross)=whisper_init_state:compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type:1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt:0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device:Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrency= trueggml_metal_init: use graph optimizetruewhisper_backend_init: usingBLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size9.44 MBwhisper_init_state: kv padsize =2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu:device 0: Metal (type: 1)whisper_backend_init_gpu: found GPUdevice 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init:use graph optimize =truewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15T11:53:17.637552ZINFO screenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunks2026-05-15T11:54:01.6843202INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=click)100% [8•Fri 15 May 11:54:03181ec2-user@ip-10-...• *8...
|
NULL
|
-4869480545776328645
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorRun PhpStormFileEditViewNavigateCodeLaravelRefactorRunToolsGitWindowHelpscreenpipe"₴4(iho]Jiminny Tech Day • 6h 6 m leftADOCKERO ₴1DEV (-zsh)82APP (-zsh)*3-zshscreenpipe*885ec2-user@ip-10-20-...886-ec2-user@ip-10-30-...whisper_init_state:whisper_init_state:kv padsize2.36 MBcompute buffer (conv)whisper_init_state: computebuffer (encode) =whisper_init_state:compute buffer (cross)=whisper_init_state:compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type:1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt:0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device:Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrency= trueggml_metal_init: use graph optimizetruewhisper_backend_init: usingBLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size9.44 MBwhisper_init_state: kv padsize =2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu:device 0: Metal (type: 1)whisper_backend_init_gpu: found GPUdevice 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init:use graph optimize =truewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15T11:53:17.637552ZINFO screenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunks2026-05-15T11:54:01.6843202INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=click)100% [8•Fri 15 May 11:54:03181ec2-user@ip-10-...• *8...
|
47813
|
NULL
|
NULL
|
NULL
|
|
47816
|
1698
|
32
|
2026-05-15T08:55:05.634039+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835305634_m1.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
[{"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":"JY-20891-improve-sms-text-relays, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20891-improve-sms-text-relays<br/>109 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"169","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"102","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","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}]...
|
8724424516320409755
|
8179532969745786684
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47817
|
1698
|
33
|
2026-05-15T08:55:06.635227+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835306635_m1.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls?q=is%3Apr+author%3ALa github.com/jiminny/app/pulls?q=is%3Apr+author%3ALakyLak+is%3Aclosed...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"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,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"}]...
|
6100731569523016018
|
-5907387955481228146
|
app_switch
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47818
|
1699
|
44
|
2026-05-15T08:55:06.657656+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835306657_m2.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls?q=is%3Apr+author%3ALa github.com/jiminny/app/pulls?q=is%3Apr+author%3ALakyLak+is%3Aclosed...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr author:LakyLak is:closed...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.38627294,"width":0.007978723,"height":0.01915403},"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.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.3020279,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.3020279,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.3073471,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.32197472,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.3352726,"top":0.06464485,"width":0.018949468,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.33726728,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.35920876,"top":0.06464485,"width":0.017785905,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.36120346,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.30169547,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.30169547,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.3073471,"top":0.09936153,"width":0.025099734,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.3181516,"top":0.10574621,"width":0.011469414,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"bounds":{"left":0.33510637,"top":0.09936153,"width":0.05518617,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.34574467,"top":0.10574621,"width":0.02925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.3776596,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"bounds":{"left":0.3806516,"top":0.113727055,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.38646942,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.3929521,"top":0.09936153,"width":0.029089095,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.4039229,"top":0.10574621,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.4247008,"top":0.09936153,"width":0.03025266,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.43583778,"top":0.10574621,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.45761302,"top":0.09936153,"width":0.022938829,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.46841756,"top":0.10574621,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"bounds":{"left":0.48321143,"top":0.09936153,"width":0.05817819,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.4950133,"top":0.10574621,"width":0.04255319,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.5440492,"top":0.09936153,"width":0.03125,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.55518615,"top":0.10574621,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.57795876,"top":0.09936153,"width":0.032081116,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.5890958,"top":0.10574621,"width":0.01761968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.31565824,"top":0.14365523,"width":0.0003324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.039228722,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.2159242,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.57214093,"top":0.1452514,"width":0.08261303,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.70694816,"top":0.1452514,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.13886672,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"bounds":{"left":0.44896942,"top":0.19553073,"width":0.04488032,"height":0.1452514},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.027426861,"height":0.025538707},"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":"Filters","depth":13,"bounds":{"left":0.45329124,"top":0.19752593,"width":0.013464096,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:pr author:LakyLak is:closed","depth":11,"bounds":{"left":0.47606382,"top":0.1915403,"width":0.23105054,"height":0.025538707},"on_screen":true,"value":"is:pr author:LakyLak is:closed","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-423416427545985855
|
-6763107068349096820
|
app_switch
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr author:LakyLak is:closed...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47819
|
1699
|
45
|
2026-05-15T08:55:07.125801+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835307125_m2.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls?q=is%3Apr+author%3ALa github.com/jiminny/app/pulls?q=is%3Apr+author%3ALakyLak+is%3Aclosed...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr author:LakyLak is:closed
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.38627294,"width":0.007978723,"height":0.01915403},"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.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.3020279,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.3020279,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.3073471,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.32197472,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.3352726,"top":0.06464485,"width":0.018949468,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.33726728,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.35920876,"top":0.06464485,"width":0.017785905,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.36120346,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.30169547,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.30169547,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.3073471,"top":0.09936153,"width":0.025099734,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.3181516,"top":0.10574621,"width":0.011469414,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"bounds":{"left":0.33510637,"top":0.09936153,"width":0.05518617,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.34574467,"top":0.10574621,"width":0.02925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.3776596,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"bounds":{"left":0.3806516,"top":0.113727055,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.38646942,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.3929521,"top":0.09936153,"width":0.029089095,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.4039229,"top":0.10574621,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.4247008,"top":0.09936153,"width":0.03025266,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.43583778,"top":0.10574621,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.45761302,"top":0.09936153,"width":0.022938829,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.46841756,"top":0.10574621,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"bounds":{"left":0.48321143,"top":0.09936153,"width":0.05817819,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.4950133,"top":0.10574621,"width":0.04255319,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.5440492,"top":0.09936153,"width":0.03125,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.55518615,"top":0.10574621,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.57795876,"top":0.09936153,"width":0.032081116,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.5890958,"top":0.10574621,"width":0.01761968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.31565824,"top":0.14365523,"width":0.0003324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.039228722,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.31565824,"top":0.1452514,"width":0.2159242,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.5315825,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.57214093,"top":0.1452514,"width":0.08261303,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.654754,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.70694816,"top":0.1452514,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.13886672,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"bounds":{"left":0.44896942,"top":0.19553073,"width":0.04488032,"height":0.1452514},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"bounds":{"left":0.44896942,"top":0.1915403,"width":0.027426861,"height":0.025538707},"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":"Filters","depth":13,"bounds":{"left":0.45329124,"top":0.19752593,"width":0.013464096,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:pr author:LakyLak is:closed","depth":11,"bounds":{"left":0.47606382,"top":0.1915403,"width":0.23105054,"height":0.025538707},"on_screen":true,"value":"is:pr author:LakyLak is:closed","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"bounds":{"left":0.7124335,"top":0.1915403,"width":0.043218084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"bounds":{"left":0.7234042,"top":0.19752593,"width":0.016954787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"bounds":{"left":0.74268615,"top":0.1991221,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"bounds":{"left":0.7553192,"top":0.1915403,"width":0.049534574,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"bounds":{"left":0.7662899,"top":0.19752593,"width":0.026263298,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.79488033,"top":0.1991221,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"bounds":{"left":0.8075133,"top":0.1915403,"width":0.045711435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"bounds":{"left":0.8118351,"top":0.19752593,"width":0.03706782,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Clear current search query, filters, and sorts","depth":10,"bounds":{"left":0.44896942,"top":0.23144454,"width":0.10804521,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Clear current search query, filters, and sorts","depth":11,"bounds":{"left":0.45628324,"top":0.23144454,"width":0.10073138,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"bounds":{"left":0.45462102,"top":0.2753392,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"7 Open","depth":11,"bounds":{"left":0.46459442,"top":0.27294493,"width":0.0234375,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7 Open","depth":12,"bounds":{"left":0.47124335,"top":0.2745411,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"359 Closed","depth":11,"bounds":{"left":0.49268618,"top":0.27294493,"width":0.03357713,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"359 Closed","depth":12,"bounds":{"left":0.4993351,"top":0.2745411,"width":0.026928192,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"bounds":{"left":0.64045876,"top":0.27294493,"width":0.018284574,"height":0.016759777},"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":"Author","depth":12,"bounds":{"left":0.64045876,"top":0.2745411,"width":0.015625,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"bounds":{"left":0.6693817,"top":0.27294493,"width":0.015625,"height":0.016759777},"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":"Label","depth":12,"bounds":{"left":0.6693817,"top":0.2745411,"width":0.012965426,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"bounds":{"left":0.695645,"top":0.27294493,"width":0.02144282,"height":0.016759777},"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":"Projects","depth":13,"bounds":{"left":0.695645,"top":0.2745411,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","depth":12,"bounds":{"left":0.7290558,"top":0.27294493,"width":0.027260639,"height":0.016759777},"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":"Milestones","depth":13,"bounds":{"left":0.7290558,"top":0.2745411,"width":0.024601065,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","depth":12,"bounds":{"left":0.76828456,"top":0.27294493,"width":0.02144282,"height":0.016759777},"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":"Reviews","depth":13,"bounds":{"left":0.76828456,"top":0.2745411,"width":0.018783245,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"bounds":{"left":0.8003657,"top":0.27294493,"width":0.0234375,"height":0.016759777},"on_screen":true,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"bounds":{"left":0.8003657,"top":0.2745411,"width":0.020777926,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"bounds":{"left":0.8344415,"top":0.27294493,"width":0.013131649,"height":0.016759777},"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":"Sort","depth":12,"bounds":{"left":0.8344415,"top":0.2745411,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"bounds":{"left":0.44930187,"top":0.30327216,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"}]...
|
1544160185926423259
|
-6902718648200274770
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (30)
Pull requests
(
30
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality
Security and quality
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr author:LakyLak is:closed
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Clear current search query, filters, and sorts
Clear current search query, filters, and sorts
Select all issues
7 Open
7 Open
359 Closed
359 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list...
|
47818
|
NULL
|
NULL
|
NULL
|
|
47821
|
1699
|
46
|
2026-05-15T08:55:08.459073+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835308459_m2.jpg...
|
Firefox
|
[SRD-6848] Sidekick SMS issue - Jira — Work
|
1
|
jiminny.atlassian.net/jira/servicedesk/projects/SR jiminny.atlassian.net/jira/servicedesk/projects/SRD/queues/custom/37/SRD-6848...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.09177973,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"bounds":{"left":0.31266624,"top":0.07861133,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"bounds":{"left":0.30601728,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"bounds":{"left":0.31117022,"top":0.06344773,"width":0.039727394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
7959722679214073998
|
-4738597529617310580
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47820
|
1698
|
34
|
2026-05-15T08:55:08.491488+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835308491_m1.jpg...
|
Firefox
|
[SRD-6848] Sidekick SMS issue - Jira — Work
|
1
|
jiminny.atlassian.net/jira/servicedesk/projects/SR jiminny.atlassian.net/jira/servicedesk/projects/SRD/queues/custom/37/SRD-6848...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"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.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":11,"on_screen":true,"help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-5531143297655346415
|
-4747569544432857972
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create...
|
47817
|
NULL
|
NULL
|
NULL
|
|
47822
|
1699
|
47
|
2026-05-15T08:55:10.194789+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835310194_m2.jpg...
|
Firefox
|
[SRD-6848] Sidekick SMS issue - Jira — Work
|
1
|
jiminny.atlassian.net/jira/servicedesk/projects/SR jiminny.atlassian.net/jira/servicedesk/projects/SRD/queues/custom/37/SRD-6848...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
Queues
Queues
Create
Create
More for queues
More for queues
Team Priority
Team Priority
All open tickets
All open tickets
Star All open tickets
15
Unassigned tickets
Unassigned tickets
Star Unassigned tickets
3
Support team Queue
Support team Queue
Star Support team Queue
5
Raised by me
Raised by me
Star Raised by me
0
Assigned to me
Assigned to me
Star Assigned to me
2
Service requests
Service requests
Star Service requests
4
Platform team
Platform team
Star Platform team
2
Processing team
Processing team
Star Processing team
10
Site reliability team
Site reliability team
Star Site reliability team
0
New features requests
New features requests
Star New features requests...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.09177973,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"bounds":{"left":0.31266624,"top":0.07861133,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"bounds":{"left":0.30601728,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"bounds":{"left":0.31117022,"top":0.06344773,"width":0.039727394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"bounds":{"left":0.3179854,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"bounds":{"left":0.3231383,"top":0.06344773,"width":0.044215426,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"bounds":{"left":0.33128324,"top":0.057861134,"width":0.029421542,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":11,"bounds":{"left":0.5159575,"top":0.06264964,"width":0.24268617,"height":0.015961692},"on_screen":true,"help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"bounds":{"left":0.7669548,"top":0.057861134,"width":0.030086435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"bounds":{"left":0.77825797,"top":0.06384677,"width":0.014793883,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"bounds":{"left":0.91223407,"top":0.057861134,"width":0.035904255,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"bounds":{"left":0.92353725,"top":0.06384677,"width":0.020611702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"bounds":{"left":0.9494681,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"bounds":{"left":0.954621,"top":0.06344773,"width":0.027759308,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"bounds":{"left":0.96143615,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"bounds":{"left":0.9665891,"top":0.06344773,"width":0.010139627,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"bounds":{"left":0.9734042,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.97855717,"top":0.06344773,"width":0.017952127,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.98537236,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"bounds":{"left":0.99052525,"top":0.06344773,"width":0.009474754,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"bounds":{"left":0.30601728,"top":0.09976058,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"bounds":{"left":0.31665558,"top":0.10574621,"width":0.01662234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"bounds":{"left":0.30601728,"top":0.12529927,"width":0.071476065,"height":0.025538707},"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":"Recent","depth":15,"bounds":{"left":0.31665558,"top":0.13128492,"width":0.015458777,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Starred","depth":12,"bounds":{"left":0.30601728,"top":0.15083799,"width":0.071476065,"height":0.025538707},"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":"Starred","depth":15,"bounds":{"left":0.31665558,"top":0.15682362,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","depth":12,"bounds":{"left":0.30601728,"top":0.1763767,"width":0.071476065,"height":0.025538707},"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":"Apps","depth":15,"bounds":{"left":0.31665558,"top":0.18236233,"width":0.011635638,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Apps","depth":13,"bounds":{"left":0.37549868,"top":0.17956904,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Apps","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Spaces","depth":12,"bounds":{"left":0.30601728,"top":0.2019154,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Spaces","depth":15,"bounds":{"left":0.31665558,"top":0.20790103,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create space","depth":13,"bounds":{"left":0.35887632,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create space","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for spaces","depth":13,"bounds":{"left":0.36818483,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for spaces","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recent","depth":16,"bounds":{"left":0.31200132,"top":0.23423783,"width":0.013464096,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny (New)","depth":17,"bounds":{"left":0.31000665,"top":0.2529928,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny (New)","depth":20,"bounds":{"left":0.32064494,"top":0.25897846,"width":0.032081116,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Jiminny (New)","depth":18,"bounds":{"left":0.31133643,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create board","depth":18,"bounds":{"left":0.37749335,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create board","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Jiminny (New)","depth":18,"bounds":{"left":0.38480717,"top":0.25618514,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Jiminny (New)","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service-Desk","depth":17,"bounds":{"left":0.31000665,"top":0.27853152,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Service-Desk","depth":20,"bounds":{"left":0.32064494,"top":0.28451717,"width":0.03025266,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Service-Desk","depth":18,"bounds":{"left":0.36818483,"top":0.28172386,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Service-Desk","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Queues","depth":21,"bounds":{"left":0.31399602,"top":0.30407023,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Queues","depth":24,"bounds":{"left":0.3246343,"top":0.31005585,"width":0.017121011,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Create","depth":22,"bounds":{"left":0.35887632,"top":0.30726257,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More for queues","depth":22,"bounds":{"left":0.36818483,"top":0.30726257,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More for queues","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Team Priority","depth":23,"bounds":{"left":0.3179854,"top":0.32960895,"width":0.059507977,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Team Priority","depth":26,"bounds":{"left":0.32862368,"top":0.33559456,"width":0.029587766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"All open tickets","depth":25,"bounds":{"left":0.32197472,"top":0.35514766,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All open tickets","depth":28,"bounds":{"left":0.33261302,"top":0.36113328,"width":0.034075797,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star All open tickets","depth":26,"bounds":{"left":0.36818483,"top":0.35834,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"15","depth":28,"bounds":{"left":0.37017953,"top":0.36272946,"width":0.0039893617,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Unassigned tickets","depth":25,"bounds":{"left":0.32197472,"top":0.38068634,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Unassigned tickets","depth":28,"bounds":{"left":0.33261302,"top":0.386672,"width":0.03307846,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Unassigned tickets","depth":26,"bounds":{"left":0.36818483,"top":0.38387868,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":28,"bounds":{"left":0.37101063,"top":0.38826814,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Support team Queue","depth":25,"bounds":{"left":0.32197472,"top":0.40622506,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Support team Queue","depth":28,"bounds":{"left":0.33261302,"top":0.4122107,"width":0.03025266,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Support team Queue","depth":26,"bounds":{"left":0.36818483,"top":0.4094174,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":28,"bounds":{"left":0.37101063,"top":0.41380686,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Raised by me","depth":25,"bounds":{"left":0.32197472,"top":0.43176377,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Raised by me","depth":28,"bounds":{"left":0.33261302,"top":0.43774942,"width":0.029753989,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Raised by me","depth":26,"bounds":{"left":0.36818483,"top":0.4349561,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":28,"bounds":{"left":0.37084442,"top":0.43934557,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned to me","depth":25,"bounds":{"left":0.32197472,"top":0.45730248,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned to me","depth":28,"bounds":{"left":0.33261302,"top":0.4632881,"width":0.03174867,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Assigned to me","depth":26,"bounds":{"left":0.36818483,"top":0.46049482,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2","depth":28,"bounds":{"left":0.37101063,"top":0.46488428,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Service requests","depth":25,"bounds":{"left":0.32197472,"top":0.4828412,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service requests","depth":28,"bounds":{"left":0.33261302,"top":0.4888268,"width":0.033410903,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Service requests","depth":26,"bounds":{"left":0.36818483,"top":0.48603353,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4","depth":28,"bounds":{"left":0.37084442,"top":0.490423,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform team","depth":25,"bounds":{"left":0.32197472,"top":0.5083799,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform team","depth":28,"bounds":{"left":0.33261302,"top":0.5143655,"width":0.031083776,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Platform team","depth":26,"bounds":{"left":0.36818483,"top":0.51157224,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2","depth":28,"bounds":{"left":0.37101063,"top":0.5159617,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Processing team","depth":25,"bounds":{"left":0.32197472,"top":0.5339186,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Processing team","depth":28,"bounds":{"left":0.33261302,"top":0.53990424,"width":0.03307846,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Processing team","depth":26,"bounds":{"left":0.36818483,"top":0.5371109,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10","depth":28,"bounds":{"left":0.37017953,"top":0.5415004,"width":0.0039893617,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Site reliability team","depth":25,"bounds":{"left":0.32197472,"top":0.5594573,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Site reliability team","depth":28,"bounds":{"left":0.33261302,"top":0.5654429,"width":0.03274601,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Site reliability team","depth":26,"bounds":{"left":0.36818483,"top":0.56264967,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":28,"bounds":{"left":0.37084442,"top":0.56703913,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New features requests","depth":25,"bounds":{"left":0.32197472,"top":0.584996,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New features requests","depth":28,"bounds":{"left":0.33261302,"top":0.59098166,"width":0.032579787,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star New features requests","depth":26,"bounds":{"left":0.36818483,"top":0.58818835,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-2857927965577627929
|
-7911366982642121692
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
Queues
Queues
Create
Create
More for queues
More for queues
Team Priority
Team Priority
All open tickets
All open tickets
Star All open tickets
15
Unassigned tickets
Unassigned tickets
Star Unassigned tickets
3
Support team Queue
Support team Queue
Star Support team Queue
5
Raised by me
Raised by me
Star Raised by me
0
Assigned to me
Assigned to me
Star Assigned to me
2
Service requests
Service requests
Star Service requests
4
Platform team
Platform team
Star Platform team
2
Processing team
Processing team
Star Processing team
10
Site reliability team
Site reliability team
Star Site reliability team
0
New features requests
New features requests
Star New features requests...
|
47821
|
NULL
|
NULL
|
NULL
|
|
47823
|
1699
|
48
|
2026-05-15T08:55:13.206070+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835313206_m2.jpg...
|
Firefox
|
[SRD-6848] Sidekick SMS issue - Jira — Work
|
1
|
jiminny.atlassian.net/jira/servicedesk/projects/SR jiminny.atlassian.net/jira/servicedesk/projects/SRD/queues/custom/37/SRD-6848...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
Queues
Queues
Create
Create
More for queues
More for queues
Team Priority
Team Priority
All open tickets
All open tickets
Star All open tickets
15
Unassigned tickets
Unassigned tickets
Star Unassigned tickets
3
Support team Queue
Support team Queue
Star Support team Queue
5
Raised by me
Raised by me
Star Raised by me
0
Assigned to me
Assigned to me
Star Assigned to me
2
Service requests
Service requests
Star Service requests
4
Platform team
Platform team
Star Platform team
2
Processing team
Processing team
Star Processing team
10
Site reliability team
Site reliability team
Star Site reliability team
0
New features requests
New features requests
Star New features requests
0
InfoSec issues
InfoSec issues
Star InfoSec issues
0
Ready for Customer
Ready for Customer
Star Ready for Customer
2
Resolved tickets
Resolved tickets
Star Resolved tickets
999+
View all queues
View all queues
Service requests...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.09177973,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"bounds":{"left":0.31266624,"top":0.07861133,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"bounds":{"left":0.30601728,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"bounds":{"left":0.31117022,"top":0.06344773,"width":0.039727394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"bounds":{"left":0.3179854,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"bounds":{"left":0.3231383,"top":0.06344773,"width":0.044215426,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"bounds":{"left":0.33128324,"top":0.057861134,"width":0.029421542,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":11,"bounds":{"left":0.5159575,"top":0.06264964,"width":0.24268617,"height":0.015961692},"on_screen":true,"help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"bounds":{"left":0.7669548,"top":0.057861134,"width":0.030086435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"bounds":{"left":0.77825797,"top":0.06384677,"width":0.014793883,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"bounds":{"left":0.91223407,"top":0.057861134,"width":0.035904255,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"bounds":{"left":0.92353725,"top":0.06384677,"width":0.020611702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"bounds":{"left":0.9494681,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"bounds":{"left":0.954621,"top":0.06344773,"width":0.027759308,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"bounds":{"left":0.96143615,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"bounds":{"left":0.9665891,"top":0.06344773,"width":0.010139627,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"bounds":{"left":0.9734042,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.97855717,"top":0.06344773,"width":0.017952127,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.98537236,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"bounds":{"left":0.99052525,"top":0.06344773,"width":0.009474754,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"bounds":{"left":0.30601728,"top":0.09976058,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"bounds":{"left":0.31665558,"top":0.10574621,"width":0.01662234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"bounds":{"left":0.30601728,"top":0.12529927,"width":0.071476065,"height":0.025538707},"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":"Recent","depth":15,"bounds":{"left":0.31665558,"top":0.13128492,"width":0.015458777,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Starred","depth":12,"bounds":{"left":0.30601728,"top":0.15083799,"width":0.071476065,"height":0.025538707},"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":"Starred","depth":15,"bounds":{"left":0.31665558,"top":0.15682362,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","depth":12,"bounds":{"left":0.30601728,"top":0.1763767,"width":0.071476065,"height":0.025538707},"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":"Apps","depth":15,"bounds":{"left":0.31665558,"top":0.18236233,"width":0.011635638,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Apps","depth":13,"bounds":{"left":0.37549868,"top":0.17956904,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Apps","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Spaces","depth":12,"bounds":{"left":0.30601728,"top":0.2019154,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Spaces","depth":15,"bounds":{"left":0.31665558,"top":0.20790103,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create space","depth":13,"bounds":{"left":0.35887632,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create space","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for spaces","depth":13,"bounds":{"left":0.36818483,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for spaces","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recent","depth":16,"bounds":{"left":0.31200132,"top":0.23423783,"width":0.013464096,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny (New)","depth":17,"bounds":{"left":0.31000665,"top":0.2529928,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny (New)","depth":20,"bounds":{"left":0.32064494,"top":0.25897846,"width":0.032081116,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Jiminny (New)","depth":18,"bounds":{"left":0.31133643,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create board","depth":18,"bounds":{"left":0.37749335,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create board","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Jiminny (New)","depth":18,"bounds":{"left":0.38480717,"top":0.25618514,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Jiminny (New)","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service-Desk","depth":17,"bounds":{"left":0.31000665,"top":0.27853152,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Service-Desk","depth":20,"bounds":{"left":0.32064494,"top":0.28451717,"width":0.03025266,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Service-Desk","depth":18,"bounds":{"left":0.36818483,"top":0.28172386,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Service-Desk","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Queues","depth":21,"bounds":{"left":0.31399602,"top":0.30407023,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Queues","depth":24,"bounds":{"left":0.3246343,"top":0.31005585,"width":0.017121011,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Create","depth":22,"bounds":{"left":0.35887632,"top":0.30726257,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More for queues","depth":22,"bounds":{"left":0.36818483,"top":0.30726257,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More for queues","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Team Priority","depth":23,"bounds":{"left":0.3179854,"top":0.32960895,"width":0.059507977,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Team Priority","depth":26,"bounds":{"left":0.32862368,"top":0.33559456,"width":0.029587766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"All open tickets","depth":25,"bounds":{"left":0.32197472,"top":0.35514766,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All open tickets","depth":28,"bounds":{"left":0.33261302,"top":0.36113328,"width":0.034075797,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star All open tickets","depth":26,"bounds":{"left":0.36818483,"top":0.35834,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"15","depth":28,"bounds":{"left":0.37017953,"top":0.36272946,"width":0.0039893617,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Unassigned tickets","depth":25,"bounds":{"left":0.32197472,"top":0.38068634,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Unassigned tickets","depth":28,"bounds":{"left":0.33261302,"top":0.386672,"width":0.03307846,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Unassigned tickets","depth":26,"bounds":{"left":0.36818483,"top":0.38387868,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":28,"bounds":{"left":0.37101063,"top":0.38826814,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Support team Queue","depth":25,"bounds":{"left":0.32197472,"top":0.40622506,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Support team Queue","depth":28,"bounds":{"left":0.33261302,"top":0.4122107,"width":0.03025266,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Support team Queue","depth":26,"bounds":{"left":0.36818483,"top":0.4094174,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":28,"bounds":{"left":0.37101063,"top":0.41380686,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Raised by me","depth":25,"bounds":{"left":0.32197472,"top":0.43176377,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Raised by me","depth":28,"bounds":{"left":0.33261302,"top":0.43774942,"width":0.029753989,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Raised by me","depth":26,"bounds":{"left":0.36818483,"top":0.4349561,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":28,"bounds":{"left":0.37084442,"top":0.43934557,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned to me","depth":25,"bounds":{"left":0.32197472,"top":0.45730248,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned to me","depth":28,"bounds":{"left":0.33261302,"top":0.4632881,"width":0.03174867,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Assigned to me","depth":26,"bounds":{"left":0.36818483,"top":0.46049482,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2","depth":28,"bounds":{"left":0.37101063,"top":0.46488428,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Service requests","depth":25,"bounds":{"left":0.32197472,"top":0.4828412,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service requests","depth":28,"bounds":{"left":0.33261302,"top":0.4888268,"width":0.033410903,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Service requests","depth":26,"bounds":{"left":0.36818483,"top":0.48603353,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4","depth":28,"bounds":{"left":0.37084442,"top":0.490423,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform team","depth":25,"bounds":{"left":0.32197472,"top":0.5083799,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform team","depth":28,"bounds":{"left":0.33261302,"top":0.5143655,"width":0.031083776,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Platform team","depth":26,"bounds":{"left":0.36818483,"top":0.51157224,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2","depth":28,"bounds":{"left":0.37101063,"top":0.5159617,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Processing team","depth":25,"bounds":{"left":0.32197472,"top":0.5339186,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Processing team","depth":28,"bounds":{"left":0.33261302,"top":0.53990424,"width":0.03307846,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Processing team","depth":26,"bounds":{"left":0.36818483,"top":0.5371109,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10","depth":28,"bounds":{"left":0.37017953,"top":0.5415004,"width":0.0039893617,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Site reliability team","depth":25,"bounds":{"left":0.32197472,"top":0.5594573,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Site reliability team","depth":28,"bounds":{"left":0.33261302,"top":0.5654429,"width":0.03274601,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Site reliability team","depth":26,"bounds":{"left":0.36818483,"top":0.56264967,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":28,"bounds":{"left":0.37084442,"top":0.56703913,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New features requests","depth":25,"bounds":{"left":0.32197472,"top":0.584996,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New features requests","depth":28,"bounds":{"left":0.33261302,"top":0.59098166,"width":0.032579787,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star New features requests","depth":26,"bounds":{"left":0.36818483,"top":0.58818835,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":28,"bounds":{"left":0.37084442,"top":0.5925778,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"InfoSec issues","depth":25,"bounds":{"left":0.32197472,"top":0.6105347,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"InfoSec issues","depth":28,"bounds":{"left":0.33261302,"top":0.61652035,"width":0.03324468,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star InfoSec issues","depth":26,"bounds":{"left":0.36818483,"top":0.61372703,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":28,"bounds":{"left":0.37084442,"top":0.6181165,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Ready for Customer","depth":25,"bounds":{"left":0.32197472,"top":0.6360734,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ready for Customer","depth":28,"bounds":{"left":0.33261302,"top":0.6420591,"width":0.032912236,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Ready for Customer","depth":26,"bounds":{"left":0.36818483,"top":0.6392658,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2","depth":28,"bounds":{"left":0.37101063,"top":0.64365524,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Resolved tickets","depth":25,"bounds":{"left":0.32197472,"top":0.66161215,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Resolved tickets","depth":28,"bounds":{"left":0.33261302,"top":0.6675978,"width":0.027094414,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Resolved tickets","depth":26,"bounds":{"left":0.36353058,"top":0.66480446,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"999+","depth":28,"bounds":{"left":0.3648604,"top":0.6691939,"width":0.009973404,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View all queues","depth":23,"bounds":{"left":0.3179854,"top":0.68715084,"width":0.059507977,"height":0.025538707},"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":"View all queues","depth":26,"bounds":{"left":0.32862368,"top":0.69313645,"width":0.034906916,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service requests","depth":21,"bounds":{"left":0.31399602,"top":0.7126895,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7248643591495717758
|
150067554224489508
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
Queues
Queues
Create
Create
More for queues
More for queues
Team Priority
Team Priority
All open tickets
All open tickets
Star All open tickets
15
Unassigned tickets
Unassigned tickets
Star Unassigned tickets
3
Support team Queue
Support team Queue
Star Support team Queue
5
Raised by me
Raised by me
Star Raised by me
0
Assigned to me
Assigned to me
Star Assigned to me
2
Service requests
Service requests
Star Service requests
4
Platform team
Platform team
Star Platform team
2
Processing team
Processing team
Star Processing team
10
Site reliability team
Site reliability team
Star Site reliability team
0
New features requests
New features requests
Star New features requests
0
InfoSec issues
InfoSec issues
Star InfoSec issues
0
Ready for Customer
Ready for Customer
Star Ready for Customer
2
Resolved tickets
Resolved tickets
Star Resolved tickets
999+
View all queues
View all queues
Service requests...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47824
|
1699
|
49
|
2026-05-15T08:55:21.574360+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835321574_m2.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.15259309,"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":"JY-20891-improve-sms-text-relays, menu","depth":5,"bounds":{"left":0.19115691,"top":0.019952115,"width":0.0944149,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20891-improve-sms-text-relays<br/>109 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8078458,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8231383,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.91522604,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9265292,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9378325,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96575797,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.97706115,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.98836434,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.4162234,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"169","depth":4,"bounds":{"left":0.4261968,"top":0.17478053,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.4401596,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"102","depth":4,"bounds":{"left":0.45013297,"top":0.17478053,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.46409574,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"}]...
|
1886851984516997009
|
-8132290250804057150
|
app_switch
|
hybrid
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
ActivityFllesLaterPhpStormViewINavicareCodeLaravelJiminny...vsStarre• jiminny-x-integrati..8 platform-inner-team® Channels# ai-chapter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofa-office# support# thank-yous# the people of fimi..• Direct messages8P. Stoyan TomovQ. Galya Dimitrova EP. Aneliya Angelovaa Vasil Vasilev#reMessag) Circ• DerProlag;Messag+ AaKeractorTOOISWindowmelpFV favsco.js v°9 JY-20891-improve-sms-text-relays k vProject© InviteUserToTeamAction.php© CrmActivityService.phpM+ WEBHOOK FILTERING MPLEMENTATIспескалокешукеmоtemateh.pnp© RematchActivityOnCrmObjectDetach.phpih External Librariesv = Scratches and ConsolesDatabase Consoles© Activity.php x] © UpdateCrmData.phpV dEUA console (EU]4 DEAL RISKS [EU]cLass Activity extends Model implementsoublic tunction uodate ctvrvermbatalarrav srecords): vordiA4 A 169 X4 X102 24 A VA DI [EU]A EU [EU]v A jiminny@localhost2121A console (jiminny@localhost]DI [jiminny@localhost]if ($this-›stage_id === null && $stage) {$this->stage_id = $stage->id;A HS_local [jiminny@localhost]21232124A SF [iiminny@localhost)A zoho_dev [jiminny@localhost]• & PROD2127if ($opportunity && $this->opportunity_id |== $opportunity->id) {$this->opportunity_id = $opportunity->id;console PRODA console_1 [PROD]& DIIPROD.2131if (Sopportunity && Sthis->value !== $opportunity->value) {sunis->value = sopporcunity-›valueDLФA> AQAIV APA PROD2133¿ console PA PRODI¿ console 1IPA PRODIIA console 2 PA PRODI console 3 leA PRODI console 4 l0AI PRODd console 5 laAI PRODIIA console_6 [QAI PROD]21352136213721381215921402141// Always set contact_id when available, regardless of account_id statuif (Sthis->contact id === null && Scontact) {$this->contact_id = $contact->id;A console 7 lGAI PRODII$this->save();f elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_io=Also uodate the parent activity if required. checkina we don't creatSthis-slead id = null:=663664—665-666 v668=669670$72676Services+,o,cy M DatahaceV AEUteamsl accountsstagesA console~A jiminny@localhostLHS localA SFV A PROD« console 1S 738 msV 4 QAI PRODdconsole 7> ASTAGING* Docker# OutputunD iminny.text relays XTx,DDL7 Q GG4Đ32412Ouuid (UUID)42fb40c5-62a4-175c-bd68-f18e3513461a! email_providergsuiteemail_provider_id19e1447dea629ed0IDemail_sent_at2026-05-10 23:45:10I senderDE ZOETEN Scott <[EMAIL]>l recinientMeg Katsiouras <[EMAIL]›!statusfailedI code2000Dorigin_activity_id <null>(activity idcreated atupdated_at2026-05-10 23•50:092026-05-10 23-50-001 row retrieved starting from 1 in 900 ms (execution: 147 ms, fetching: 753 ms)E custom.log( scratch_8.jsonE laravel.logA console [PROD] x A console [EU)fiò accounts [EU]© FixActivitesOpportunity.phpA console_7 [QAI PROD]Tx: AutovPlaygroundselect * trom rate Limits4 SF [jiminny@localhost]f stages (EU]A HS_local [jiminny@localhost]iii teams (EU]© ImportBotRecordingJob.phpA console (STAGING)de jiminny040 A1 A40 M65 A Vselect * from automated_report_results where nedia type = 'pdf' and etatus = 2and id IN (18, 1872);select * from automated_reports where 1d = 54;SELECT * FROM users WHERE id IN (24623,29443, 29613);SELECT * FROM autonated_report-resuits WHERE uuid, to_bin(' 8227041b-afd3-4309-0248-86b803673132') = utd:=select * from text_reflays where created_at › '2026-05-01'# and id IN (32415, 32416);and id = 32412;select * from users where team_id = 2 and email like "%scott%' and id = 29510;SELECT * FROM activities WHERE uvid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uvid; # 79763436SELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statusesFROM text_relaysemail_provider_id IN ('19e2027868a64b42' , '19e2033ed8ea6b10')GROUP BY email_provider_id;stltcl 10, status.telephony_provider_id, created_atFROM activitiesWHERE 10 IN (80628/19, 8002884601SELECT id, status, code, email_sent_at, created_at, updated_atFROM text relaysJiminny Tech Day • 6h 5m left100% 1528• Fri 15 May 11:55:21Review PR tor ActivityDebug Text Relay Fall+0...Please contact support tor more intormation, quoting reterence 0626141c-2/ab-4d8c-attöPertect. The email shows.• Reference: 0626141c-27a6-4d8c-aff8-7c8820a2c656• Code: 2200Code 2200 is REASON_CODE_SENDER_MISMATCH (line 35 in EmailTextRelay.php), which means"Sender does not match the oriain activitv."This is a different text_relay record than the one we've been looking at (32416 has UUID 8x4CD18652A4D7AA2DA5268705E3B21366 ). Let me find the record with UUID 0626141c-27a6-4d8c-aff8-7c8020a2c656iisalSELECT id, uuid, status, code, sender, recipient, created_at, updated_atFROM text_relaysWHERE uuid = uuid to bin 0626141c-27a6-4d8c-aff8-7c8020a2c656'):This will show the actual valled text relav record that triagered the failure email Stovan received!© uil .A Ourincluded wekly usage quota is exhausted. Using your extra usage. Quota resets May 17, 1:00 AMAsk anything (3AL)+ <> CodeSWE-1.6CSv| +08W Windsurf Teams 666:22 UTF-8 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47825
|
1699
|
50
|
2026-05-15T08:55:26.574216+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835326574_m2.jpg...
|
Firefox
|
[SRD-6848] Sidekick SMS issue - Jira — Work
|
1
|
jiminny.atlassian.net/jira/servicedesk/projects/SR jiminny.atlassian.net/jira/servicedesk/projects/SRD/queues/custom/37/SRD-6848...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
Queues
Queues
Create
Create
More for queues
More for queues
Team Priority
Team Priority
All open tickets
All open tickets
Star All open tickets
15
Unassigned tickets
Unassigned tickets
Star Unassigned tickets
3
Support team Queue
Support team Queue
Star Support team Queue
5
Raised by me
Raised by me
Star Raised by me
0
Assigned to me
Assigned to me
Star Assigned to me
2
Service requests
Service requests
Star Service requests
4
Platform team
Platform team
Star Platform team
2
Processing team
Processing team
Star Processing team
10
Site reliability team
Site reliability team
Star Site reliability team
0
New features requests
New features requests
Star New features requests
0
InfoSec issues
InfoSec issues
Star InfoSec issues
0
Ready for Customer
Ready for Customer
Star Ready for Customer
2
Resolved tickets
Resolved tickets
Star Resolved tickets
999+
View all queues
View all queues
Service requests
Service requests
Create
Create
More for service requests
More for service requests
Incidents
Incidents
Create
Create
More for incidents
More for incidents
Reports
Reports
More actions for reports...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.09177973,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"bounds":{"left":0.31266624,"top":0.07861133,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"bounds":{"left":0.30601728,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"bounds":{"left":0.31117022,"top":0.06344773,"width":0.039727394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"bounds":{"left":0.3179854,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"bounds":{"left":0.3231383,"top":0.06344773,"width":0.044215426,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"bounds":{"left":0.33128324,"top":0.057861134,"width":0.029421542,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":11,"bounds":{"left":0.5159575,"top":0.06264964,"width":0.24268617,"height":0.015961692},"on_screen":true,"help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"bounds":{"left":0.7669548,"top":0.057861134,"width":0.030086435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"bounds":{"left":0.77825797,"top":0.06384677,"width":0.014793883,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"bounds":{"left":0.91223407,"top":0.057861134,"width":0.035904255,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"bounds":{"left":0.92353725,"top":0.06384677,"width":0.020611702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"bounds":{"left":0.9494681,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"bounds":{"left":0.954621,"top":0.06344773,"width":0.027759308,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"bounds":{"left":0.96143615,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"bounds":{"left":0.9665891,"top":0.06344773,"width":0.010139627,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"bounds":{"left":0.9734042,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.97855717,"top":0.06344773,"width":0.017952127,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.98537236,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"bounds":{"left":0.99052525,"top":0.06344773,"width":0.009474754,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"bounds":{"left":0.30601728,"top":0.09976058,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"bounds":{"left":0.31665558,"top":0.10574621,"width":0.01662234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"bounds":{"left":0.30601728,"top":0.12529927,"width":0.071476065,"height":0.025538707},"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":"Recent","depth":15,"bounds":{"left":0.31665558,"top":0.13128492,"width":0.015458777,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Starred","depth":12,"bounds":{"left":0.30601728,"top":0.15083799,"width":0.071476065,"height":0.025538707},"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":"Starred","depth":15,"bounds":{"left":0.31665558,"top":0.15682362,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","depth":12,"bounds":{"left":0.30601728,"top":0.1763767,"width":0.071476065,"height":0.025538707},"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":"Apps","depth":15,"bounds":{"left":0.31665558,"top":0.18236233,"width":0.011635638,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Apps","depth":13,"bounds":{"left":0.37549868,"top":0.17956904,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Apps","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Spaces","depth":12,"bounds":{"left":0.30601728,"top":0.2019154,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Spaces","depth":15,"bounds":{"left":0.31665558,"top":0.20790103,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create space","depth":13,"bounds":{"left":0.35887632,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create space","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for spaces","depth":13,"bounds":{"left":0.36818483,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for spaces","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recent","depth":16,"bounds":{"left":0.31200132,"top":0.23423783,"width":0.013464096,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny (New)","depth":17,"bounds":{"left":0.31000665,"top":0.2529928,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny (New)","depth":20,"bounds":{"left":0.32064494,"top":0.25897846,"width":0.032081116,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Jiminny (New)","depth":18,"bounds":{"left":0.31133643,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create board","depth":18,"bounds":{"left":0.37749335,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create board","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Jiminny (New)","depth":18,"bounds":{"left":0.38480717,"top":0.25618514,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Jiminny (New)","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service-Desk","depth":17,"bounds":{"left":0.31000665,"top":0.27853152,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Service-Desk","depth":20,"bounds":{"left":0.32064494,"top":0.28451717,"width":0.03025266,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Service-Desk","depth":18,"bounds":{"left":0.36818483,"top":0.28172386,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Service-Desk","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Queues","depth":21,"bounds":{"left":0.31399602,"top":0.30407023,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Queues","depth":24,"bounds":{"left":0.3246343,"top":0.31005585,"width":0.017121011,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Create","depth":22,"bounds":{"left":0.35887632,"top":0.30726257,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More for queues","depth":22,"bounds":{"left":0.36818483,"top":0.30726257,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More for queues","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Team Priority","depth":23,"bounds":{"left":0.3179854,"top":0.32960895,"width":0.059507977,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Team Priority","depth":26,"bounds":{"left":0.32862368,"top":0.33559456,"width":0.029587766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"All open tickets","depth":25,"bounds":{"left":0.32197472,"top":0.35514766,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All open tickets","depth":28,"bounds":{"left":0.33261302,"top":0.36113328,"width":0.034075797,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star All open tickets","depth":26,"bounds":{"left":0.36818483,"top":0.35834,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"15","depth":28,"bounds":{"left":0.37017953,"top":0.36272946,"width":0.0039893617,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Unassigned tickets","depth":25,"bounds":{"left":0.32197472,"top":0.38068634,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Unassigned tickets","depth":28,"bounds":{"left":0.33261302,"top":0.386672,"width":0.03307846,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Unassigned tickets","depth":26,"bounds":{"left":0.36818483,"top":0.38387868,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":28,"bounds":{"left":0.37101063,"top":0.38826814,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Support team Queue","depth":25,"bounds":{"left":0.32197472,"top":0.40622506,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Support team Queue","depth":28,"bounds":{"left":0.33261302,"top":0.4122107,"width":0.03025266,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Support team Queue","depth":26,"bounds":{"left":0.36818483,"top":0.4094174,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":28,"bounds":{"left":0.37101063,"top":0.41380686,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Raised by me","depth":25,"bounds":{"left":0.32197472,"top":0.43176377,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Raised by me","depth":28,"bounds":{"left":0.33261302,"top":0.43774942,"width":0.029753989,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Raised by me","depth":26,"bounds":{"left":0.36818483,"top":0.4349561,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":28,"bounds":{"left":0.37084442,"top":0.43934557,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned to me","depth":25,"bounds":{"left":0.32197472,"top":0.45730248,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned to me","depth":28,"bounds":{"left":0.33261302,"top":0.4632881,"width":0.03174867,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Assigned to me","depth":26,"bounds":{"left":0.36818483,"top":0.46049482,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2","depth":28,"bounds":{"left":0.37101063,"top":0.46488428,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Service requests","depth":25,"bounds":{"left":0.32197472,"top":0.4828412,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service requests","depth":28,"bounds":{"left":0.33261302,"top":0.4888268,"width":0.033410903,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Service requests","depth":26,"bounds":{"left":0.36818483,"top":0.48603353,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4","depth":28,"bounds":{"left":0.37084442,"top":0.490423,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform team","depth":25,"bounds":{"left":0.32197472,"top":0.5083799,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform team","depth":28,"bounds":{"left":0.33261302,"top":0.5143655,"width":0.031083776,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Platform team","depth":26,"bounds":{"left":0.36818483,"top":0.51157224,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2","depth":28,"bounds":{"left":0.37101063,"top":0.5159617,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Processing team","depth":25,"bounds":{"left":0.32197472,"top":0.5339186,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Processing team","depth":28,"bounds":{"left":0.33261302,"top":0.53990424,"width":0.03307846,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Processing team","depth":26,"bounds":{"left":0.36818483,"top":0.5371109,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10","depth":28,"bounds":{"left":0.37017953,"top":0.5415004,"width":0.0039893617,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Site reliability team","depth":25,"bounds":{"left":0.32197472,"top":0.5594573,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Site reliability team","depth":28,"bounds":{"left":0.33261302,"top":0.5654429,"width":0.03274601,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Site reliability team","depth":26,"bounds":{"left":0.36818483,"top":0.56264967,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":28,"bounds":{"left":0.37084442,"top":0.56703913,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New features requests","depth":25,"bounds":{"left":0.32197472,"top":0.584996,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New features requests","depth":28,"bounds":{"left":0.33261302,"top":0.59098166,"width":0.032579787,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star New features requests","depth":26,"bounds":{"left":0.36818483,"top":0.58818835,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":28,"bounds":{"left":0.37084442,"top":0.5925778,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"InfoSec issues","depth":25,"bounds":{"left":0.32197472,"top":0.6105347,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"InfoSec issues","depth":28,"bounds":{"left":0.33261302,"top":0.61652035,"width":0.03324468,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star InfoSec issues","depth":26,"bounds":{"left":0.36818483,"top":0.61372703,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":28,"bounds":{"left":0.37084442,"top":0.6181165,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Ready for Customer","depth":25,"bounds":{"left":0.32197472,"top":0.6360734,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ready for Customer","depth":28,"bounds":{"left":0.33261302,"top":0.6420591,"width":0.032912236,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Ready for Customer","depth":26,"bounds":{"left":0.36818483,"top":0.6392658,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2","depth":28,"bounds":{"left":0.37101063,"top":0.64365524,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Resolved tickets","depth":25,"bounds":{"left":0.32197472,"top":0.66161215,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Resolved tickets","depth":28,"bounds":{"left":0.33261302,"top":0.6675978,"width":0.027094414,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Resolved tickets","depth":26,"bounds":{"left":0.36353058,"top":0.66480446,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"999+","depth":28,"bounds":{"left":0.3648604,"top":0.6691939,"width":0.009973404,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View all queues","depth":23,"bounds":{"left":0.3179854,"top":0.68715084,"width":0.059507977,"height":0.025538707},"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":"View all queues","depth":26,"bounds":{"left":0.32862368,"top":0.69313645,"width":0.034906916,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service requests","depth":21,"bounds":{"left":0.31399602,"top":0.7126895,"width":0.06349734,"height":0.025538707},"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":"Service requests","depth":24,"bounds":{"left":0.3246343,"top":0.7186752,"width":0.03756649,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Create","depth":22,"bounds":{"left":0.37549868,"top":0.7158819,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More for service requests","depth":22,"bounds":{"left":0.37682846,"top":0.7158819,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More for service requests","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Incidents","depth":22,"bounds":{"left":0.31399602,"top":0.73822826,"width":0.06349734,"height":0.025538707},"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":"Incidents","depth":25,"bounds":{"left":0.3246343,"top":0.7442139,"width":0.021276595,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Create","depth":23,"bounds":{"left":0.37549868,"top":0.74142057,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More for incidents","depth":23,"bounds":{"left":0.37682846,"top":0.74142057,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More for incidents","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Reports","depth":19,"bounds":{"left":0.31399602,"top":0.76376694,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reports","depth":22,"bounds":{"left":0.3246343,"top":0.7697526,"width":0.017287234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for reports","depth":20,"bounds":{"left":0.37549868,"top":0.7669593,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
5044089008717869802
|
1311996258069302436
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
Queues
Queues
Create
Create
More for queues
More for queues
Team Priority
Team Priority
All open tickets
All open tickets
Star All open tickets
15
Unassigned tickets
Unassigned tickets
Star Unassigned tickets
3
Support team Queue
Support team Queue
Star Support team Queue
5
Raised by me
Raised by me
Star Raised by me
0
Assigned to me
Assigned to me
Star Assigned to me
2
Service requests
Service requests
Star Service requests
4
Platform team
Platform team
Star Platform team
2
Processing team
Processing team
Star Processing team
10
Site reliability team
Site reliability team
Star Site reliability team
0
New features requests
New features requests
Star New features requests
0
InfoSec issues
InfoSec issues
Star InfoSec issues
0
Ready for Customer
Ready for Customer
Star Ready for Customer
2
Resolved tickets
Resolved tickets
Star Resolved tickets
999+
View all queues
View all queues
Service requests
Service requests
Create
Create
More for service requests
More for service requests
Incidents
Incidents
Create
Create
More for incidents
More for incidents
Reports
Reports
More actions for reports...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47826
|
1699
|
51
|
2026-05-15T08:55:29.640246+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835329640_m2.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.15259309,"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":"JY-20891-improve-sms-text-relays, menu","depth":5,"bounds":{"left":0.19115691,"top":0.019952115,"width":0.0944149,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20891-improve-sms-text-relays<br/>109 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8078458,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8231383,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.91522604,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9265292,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9378325,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96575797,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.97706115,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.98836434,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.4162234,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"169","depth":4,"bounds":{"left":0.4261968,"top":0.17478053,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.4401596,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"102","depth":4,"bounds":{"left":0.45013297,"top":0.17478053,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.46409574,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.4737367,"top":0.17318435,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.48105052,"top":0.17318435,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.48969415,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.49833778,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.5093085,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.51795214,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.5265958,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.5375665,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.54853725,"top":0.123703115,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.57513297,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.58610374,"top":0.123703115,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7569814,"top":0.123703115,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.72639626,"top":0.14844373,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.7386968,"top":0.14844373,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.74800533,"top":0.14844373,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"65","depth":4,"bounds":{"left":0.7603058,"top":0.14844373,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.77227396,"top":0.14684756,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.77958775,"top":0.14684756,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01'\n# and id IN (32415, 32416);\nand id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01'\n# and id IN (32415, 32416);\nand id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.13863032,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8724424516320409755
|
8179532969745786684
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47827
|
1699
|
52
|
2026-05-15T08:55:32.655754+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835332655_m2.jpg...
|
Firefox
|
[SRD-6848] Sidekick SMS issue - Jira — Work
|
1
|
jiminny.atlassian.net/jira/servicedesk/projects/SR jiminny.atlassian.net/jira/servicedesk/projects/SRD/queues/custom/37/SRD-6848...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
Queues
Queues
Create
Create
More for queues
More for queues
Team Priority
Team Priority
All open tickets
All open tickets
Star All open tickets
15
Unassigned tickets
Unassigned tickets
Star Unassigned tickets
3
Support team Queue
Support team Queue
Star Support team Queue
5
Raised by me
Raised by me
Star Raised by me
0
Assigned to me
Assigned to me
Star Assigned to me
2
Service requests
Service requests...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.09177973,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"bounds":{"left":0.31266624,"top":0.07861133,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"bounds":{"left":0.30601728,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"bounds":{"left":0.31117022,"top":0.06344773,"width":0.039727394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"bounds":{"left":0.3179854,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"bounds":{"left":0.3231383,"top":0.06344773,"width":0.044215426,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"bounds":{"left":0.33128324,"top":0.057861134,"width":0.029421542,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":11,"bounds":{"left":0.5159575,"top":0.06264964,"width":0.24268617,"height":0.015961692},"on_screen":true,"help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"bounds":{"left":0.7669548,"top":0.057861134,"width":0.030086435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"bounds":{"left":0.77825797,"top":0.06384677,"width":0.014793883,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"bounds":{"left":0.91223407,"top":0.057861134,"width":0.035904255,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"bounds":{"left":0.92353725,"top":0.06384677,"width":0.020611702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"bounds":{"left":0.9494681,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"bounds":{"left":0.954621,"top":0.06344773,"width":0.027759308,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"bounds":{"left":0.96143615,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"bounds":{"left":0.9665891,"top":0.06344773,"width":0.010139627,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"bounds":{"left":0.9734042,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.97855717,"top":0.06344773,"width":0.017952127,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.98537236,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"bounds":{"left":0.99052525,"top":0.06344773,"width":0.009474754,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"bounds":{"left":0.30601728,"top":0.09976058,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"bounds":{"left":0.31665558,"top":0.10574621,"width":0.01662234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"bounds":{"left":0.30601728,"top":0.12529927,"width":0.071476065,"height":0.025538707},"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":"Recent","depth":15,"bounds":{"left":0.31665558,"top":0.13128492,"width":0.015458777,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Starred","depth":12,"bounds":{"left":0.30601728,"top":0.15083799,"width":0.071476065,"height":0.025538707},"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":"Starred","depth":15,"bounds":{"left":0.31665558,"top":0.15682362,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","depth":12,"bounds":{"left":0.30601728,"top":0.1763767,"width":0.071476065,"height":0.025538707},"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":"Apps","depth":15,"bounds":{"left":0.31665558,"top":0.18236233,"width":0.011635638,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Apps","depth":13,"bounds":{"left":0.37549868,"top":0.17956904,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Apps","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Spaces","depth":12,"bounds":{"left":0.30601728,"top":0.2019154,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Spaces","depth":15,"bounds":{"left":0.31665558,"top":0.20790103,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create space","depth":13,"bounds":{"left":0.35887632,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create space","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for spaces","depth":13,"bounds":{"left":0.36818483,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for spaces","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recent","depth":16,"bounds":{"left":0.31200132,"top":0.23423783,"width":0.013464096,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny (New)","depth":17,"bounds":{"left":0.31000665,"top":0.2529928,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny (New)","depth":20,"bounds":{"left":0.32064494,"top":0.25897846,"width":0.032081116,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Jiminny (New)","depth":18,"bounds":{"left":0.31133643,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create board","depth":18,"bounds":{"left":0.37749335,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create board","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Jiminny (New)","depth":18,"bounds":{"left":0.38480717,"top":0.25618514,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Jiminny (New)","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service-Desk","depth":17,"bounds":{"left":0.31000665,"top":0.27853152,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Service-Desk","depth":20,"bounds":{"left":0.32064494,"top":0.28451717,"width":0.03025266,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Service-Desk","depth":18,"bounds":{"left":0.36818483,"top":0.28172386,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Service-Desk","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Queues","depth":21,"bounds":{"left":0.31399602,"top":0.30407023,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Queues","depth":24,"bounds":{"left":0.3246343,"top":0.31005585,"width":0.017121011,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Create","depth":22,"bounds":{"left":0.35887632,"top":0.30726257,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More for queues","depth":22,"bounds":{"left":0.36818483,"top":0.30726257,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More for queues","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Team Priority","depth":23,"bounds":{"left":0.3179854,"top":0.32960895,"width":0.059507977,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Team Priority","depth":26,"bounds":{"left":0.32862368,"top":0.33559456,"width":0.029587766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"All open tickets","depth":25,"bounds":{"left":0.32197472,"top":0.35514766,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All open tickets","depth":28,"bounds":{"left":0.33261302,"top":0.36113328,"width":0.034075797,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star All open tickets","depth":26,"bounds":{"left":0.36818483,"top":0.35834,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"15","depth":28,"bounds":{"left":0.37017953,"top":0.36272946,"width":0.0039893617,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Unassigned tickets","depth":25,"bounds":{"left":0.32197472,"top":0.38068634,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Unassigned tickets","depth":28,"bounds":{"left":0.33261302,"top":0.386672,"width":0.03307846,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Unassigned tickets","depth":26,"bounds":{"left":0.36818483,"top":0.38387868,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":28,"bounds":{"left":0.37101063,"top":0.38826814,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Support team Queue","depth":25,"bounds":{"left":0.32197472,"top":0.40622506,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Support team Queue","depth":28,"bounds":{"left":0.33261302,"top":0.4122107,"width":0.03025266,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Support team Queue","depth":26,"bounds":{"left":0.36818483,"top":0.4094174,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":28,"bounds":{"left":0.37101063,"top":0.41380686,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Raised by me","depth":25,"bounds":{"left":0.32197472,"top":0.43176377,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Raised by me","depth":28,"bounds":{"left":0.33261302,"top":0.43774942,"width":0.029753989,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Raised by me","depth":26,"bounds":{"left":0.36818483,"top":0.4349561,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":28,"bounds":{"left":0.37084442,"top":0.43934557,"width":0.0026595744,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned to me","depth":25,"bounds":{"left":0.32197472,"top":0.45730248,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned to me","depth":28,"bounds":{"left":0.33261302,"top":0.4632881,"width":0.03174867,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Star Assigned to me","depth":26,"bounds":{"left":0.36818483,"top":0.46049482,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2","depth":28,"bounds":{"left":0.37101063,"top":0.46488428,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Service requests","depth":25,"bounds":{"left":0.32197472,"top":0.4828412,"width":0.055518616,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service requests","depth":28,"bounds":{"left":0.33261302,"top":0.4888268,"width":0.033410903,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
8506017716519115436
|
-7911375778735176532
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Close tab
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
Queues
Queues
Create
Create
More for queues
More for queues
Team Priority
Team Priority
All open tickets
All open tickets
Star All open tickets
15
Unassigned tickets
Unassigned tickets
Star Unassigned tickets
3
Support team Queue
Support team Queue
Star Support team Queue
5
Raised by me
Raised by me
Star Raised by me
0
Assigned to me
Assigned to me
Star Assigned to me
2
Service requests
Service requests...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47828
|
1699
|
53
|
2026-05-15T08:55:35.697831+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835335697_m2.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.15259309,"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":"JY-20891-improve-sms-text-relays, menu","depth":5,"bounds":{"left":0.19115691,"top":0.019952115,"width":0.0944149,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20891-improve-sms-text-relays<br/>109 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8078458,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8231383,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.91522604,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9265292,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9378325,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96575797,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-8413119186166400704
|
-8348537731023393598
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
ActivityFllesLaterPhpStormViewINavicareCodeLaravelKeractorTOOISWindowmelpFV favsco.js v°9 JY-20891-improve-sms-text-relays k vJiminny...vsStarre• jiminny-x-integrati..8 platform-inner-team® Channels# ai-chapter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofa-office# support# thank-yous# the people of fimi..Project© InviteUserToTeamAction.php© CrmActivityService.php#reM+ WEBHOOK FILTERING IMPLEMENTATIспескалокешукеmоtемatch.php© RematchActivityOnCrmObjectDetach.phpih External LibrariesMessagv = Scratches and ConsolesDatabase Consoles© Activity.php x] © UpdateCrmData.phpV dEUA console (EU]) Circ4 DEAL RISKS [EU]cLass Activity extends Model implements44 A189 X 4 X102 2.4 A 658• DerA DI [EU]oublic tunction uodate ctvrvermbatalarrav srecords): vordiA EU [EU]2121661Prov A jiminny@localhostif ($this-›stage_id === null && $stage) {A console (jiminny@localhost]DI [jiminny@localhost]2123lag;A HS_local [jiminny@localhost]2124$this-›stage_id = $stage->id;=663664A SF [iiminny@localhost)A zoho_dev [jiminny@localhost]if ($opportunity && $this->opportunity_id |== $opportunity->id) {• & PROD2127$this->opportunity_id = $opportunity->id;=60evconsole PRODA console_1 [PROD]if (Sopportunity && Sthis->value !== Sopportunity->value) {& DIIPROD.6702131sunis->value = sopporcunaty->valueDLФA$72> AQAIV APA PROD2133¿ console PA PRODI2135// Always set contact_id when available, regardless of account_id statuif (Sthis->contact id === null && Scontact) {¿ console 1IPA PRODII2136A console 2 PA PROD2137$this->contact_id = $contact->id;I console 3 leA PROD2138I console 4 l0AI PROD12159d console 5 laAI PRODII• Direct messages2140$this->save();A console_6 [QAI PROD]f elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_io=2141Also uodate the parent activity if required. checkina we don't creatA console 7 lGAI PRODII8P. Stoyan TomovSthis-slead id = null:Q. Galya Dimitrova EP. Aneliya AngelovaMessaga Vasil Vasilev+ AaE custom.log( scratch_8.jsonE laravel.log4 SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD] x A console [EU)fiò accounts [EU]f stages (EU]iii teams (EU]© ImportBotRecordingJob.php© FixActivitesOpportunity.phpA console_7 [QAI PROD]A console (STAGING)Tx: AutovPlaygroundselect * trom rate Limitsde jiminny040 A1 A40 M65 A Vselect * from automated_report_results where nedia type = 'pdf' and etatus = 2and id IN (18, 1872);select * from automated_reports where 1d = 54;SELECT * FROM users WHERE id IN (24623,29443, 29613);SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;=select * from text_reflays where created_at › '2026-05-01'# and id IN (32415, 32416);and id = 32412;select * from users where team_id = 2 and email like "%scott%' and id = 29510;SELECT * FROM activities WHERE uvid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uvid; # 79763436SELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statusesFROM text_relaysemail_provider_id IN ('19e2027868a64b42' , '19e2033ed8ea6b10')GROUP BY email_provider_id;stltcl 10, status.telephony_provider_id, created_atFRun activitlesWHERE 10 IN (80628/19 8002884601SELECT id, status, code, email_sent_at, created_at, updated_atFROM text relaysServices+,o,cy M DatahaceV AEUteamsl accountsstagesA console~A jiminny@localhostLHS localA SFV A PROD« console 1S 738 msV 4 QAI PRODdconsole 7> ASTAGING* Docker# OutputunD iminny.text relays XTx,DDL7 Q GG4Đ32412Ouuid (UUID)42fb40c5-62a4-175c-bd68-f18e3513461a! email_providergsuiteemail_provider_id19e1447dea629ed0IDemail_sent_at2026-05-10 23:45:10I senderDE ZOETEN Scott <[EMAIL]>l recinientMeg Katsiouras <[EMAIL]›!statusfailedI code2000Dorigin_activity_id <null>(activity idcreated atupdated_at2026-05-10 23•50:092026-05-10 23-50-001 row retrieved starting from 1 in 900 ms (execution: 147 ms, fetching: 753 ms)Jiminny Tech Day • 6h 5m left100% 1528• Fri 15 May 11:55:35Review PR tor ActivityDebug Text Relay Fall+0...Please contact support tor more intormation, quoting reterence 0626141c-2/ab-4d8c-attöPertect. The email shows.• Reference: 0626141c-27a6-4d8c-aff8-7c8820a2c656• Code: 2200Code 2200 is REASON_CODE_SENDER_MISMATCH (line 35 in EmailTextRelay.php), which means"Sender does not match the oriain activitv."This is a different text_relay record than the one we've been looking at (32416 has UUID 8x4CD18652A4D7AA2DA5268705E3B21366 ). Let me find the record with UUID 0626141c-27a6-4d8c-aff8-7c8020a2c656iisalSELECT id, uuid, status, code, sender, recipient, created_at, updated_atFROM text_relaysWHERE uuid = uuid to bin 0626141c-27a6-4d8c-aff8-7c8020a2c656'):This will show the actual valled text relav record that triagered the failure email Stovan received!© uil .A Ourincluded wekly usage quota is exhausted. Using your extra usage. Quota resets May 17, 1:00 AMAsk anything (3AL)+ <> CodeSWE-1.6CSv| +08W Windsurf Teams 666:22 UTF-8 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47830
|
1699
|
54
|
2026-05-15T08:55:37.396679+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835337396_m2.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.15259309,"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":"JY-20891-improve-sms-text-relays, menu","depth":5,"bounds":{"left":0.19115691,"top":0.019952115,"width":0.0944149,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20891-improve-sms-text-relays<br/>109 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8078458,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8231383,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.91522604,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9265292,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9378325,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96575797,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.97706115,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.98836434,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.4162234,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"169","depth":4,"bounds":{"left":0.4261968,"top":0.17478053,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.4401596,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"102","depth":4,"bounds":{"left":0.45013297,"top":0.17478053,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.46409574,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.4737367,"top":0.17318435,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.48105052,"top":0.17318435,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.48969415,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.49833778,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.5093085,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.51795214,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.5265958,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.5375665,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.54853725,"top":0.123703115,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.57513297,"top":0.123703115,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.58610374,"top":0.123703115,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7569814,"top":0.123703115,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.72639626,"top":0.14844373,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.7386968,"top":0.14844373,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.74800533,"top":0.14844373,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"65","depth":4,"bounds":{"left":0.7603058,"top":0.14844373,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.77227396,"top":0.14684756,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.77958775,"top":0.14684756,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01'\n# and id IN (32415, 32416);\nand id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01'\n# and id IN (32415, 32416);\nand id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.13863032,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8724424516320409755
|
8179532969745786684
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
47828
|
NULL
|
NULL
|
NULL
|
|
47829
|
1698
|
35
|
2026-05-15T08:55:37.404496+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835337404_m1.jpg...
|
PhpStorm
|
faVsco.js – console [PROD]
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
[{"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":"JY-20891-improve-sms-text-relays, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20891-improve-sms-text-relays<br/>109 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"169","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"102","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Carbon\\Carbon;\nuse Database\\Factories\\ActivityFactory;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Database\\Eloquent;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ElasticSearch;\nuse Jiminny\\Component\\MeetingBot;\nuse Jiminny\\Component\\Model\\BitwiseFlagTrait;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Component\\Uuid\\UuidAwareInterface;\nuse Jiminny\\Component\\Workflow;\nuse Jiminny\\Contracts;\nuse Jiminny\\Contracts\\Crm\\ProspectInterface;\nuse Jiminny\\DTO\\ImportCall\\Call;\nuse Jiminny\\Events\\Activities\\ActivityTypeUpdated;\nuse Jiminny\\Events\\Activities\\ActivityUpdated;\nuse Jiminny\\Events\\Activities\\ProspectUpdated;\nuse Jiminny\\Events\\Activities\\StageUpdated;\nuse Jiminny\\Events\\Activities\\StatusUpdated;\nuse Jiminny\\Events\\Activities\\TitleUpdated;\nuse Jiminny\\Exceptions\\InvalidArgumentException as InvalidArgumentJiminnyException;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Activity\\ActivitySummaryLog;\nuse Jiminny\\Models\\Activity\\ActivityUploadSetting;\nuse Jiminny\\Models\\Activity\\AvailabilityNotification;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Log;\nuse Jiminny\\Models\\Activity\\Message;\nuse Jiminny\\Models\\Activity\\Moment;\nuse Jiminny\\Models\\Activity\\Note;\nuse Jiminny\\Models\\Activity\\ParticipantSpeech;\nuse Jiminny\\Models\\Activity\\Play;\nuse Jiminny\\Models\\Activity\\Question;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\Activity\\Snapshot;\nuse Jiminny\\Models\\Activity\\Stats;\nuse Jiminny\\Models\\Activity\\SubscriptionSet;\nuse Jiminny\\Models\\Activity\\TopicTrigger;\nuse Jiminny\\Models\\Activity\\Transcription;\nuse Jiminny\\Models\\Calendar\\CalendarEvent;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\ElasticSearch\\ActivityElasticSearchTrait;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Participant\\Connection;\nuse Jiminny\\Models\\Playlist\\Activity as PlaylistActivity;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataByStrategy;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverFactory;\nuse Jiminny\\Services\\Activity\\Import\\DataResolvers\\UpdateCrmDataResolverInterface;\nuse Jiminny\\Traits\\Enums;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Jiminny\\Utils\\CurrencyFormatter;\nuse NumberFormatter;\n\nuse function in_array;\n\n/**\n * Jiminny\\Models\\Activity\n *\n * @property null|int $auto_score filled from ES hydrator, not in DB!\n * @property-read Account|null $account\n * @property-read CalendarEvent|null $calendarEvent\n * @property-read Contact|null $contact\n * @property-read Lead|null $lead\n * @property-read Opportunity|null $opportunity\n * @property-read Stage|null $stage\n * @property int $id\n * @property mixed|null $uuid\n * @property string|null $source\n * @property string|null $external_id\n * @property string $provider\n * @property string|null $location\n * @property string|null $telephony_provider_id\n * @property int|null $from_participant_id\n * @property int|null $to_participant_id\n * @property int|null $device_id\n * @property string|null $type\n * @property int|null $playbook_category_id\n * @property int $user_id\n * @property int|null $lead_id\n * @property int|null $account_id\n * @property int|null $contact_id\n * @property int|null $opportunity_id\n * @property int|null $stage_id\n * @property string|null $value\n * @property int|null $crm_configuration_id\n * @property string|null $crm_provider_id\n * @property string|null $language\n * @property int|null $transcription_id\n * @property int $duration\n * @property string $status\n * @property int|null $on_air\n * @property int|null $calendar_event_id\n * @property string $recording_state\n * @property bool|null $recording_preference\n * @property int $recording_reason_code\n * @property int $summary_reminder_sent\n * @property \\Illuminate\\Support\\Carbon|null $log_reminder_sent_at\n * @property \\Illuminate\\Support\\Carbon|null $organizer_notified_at\n * @property bool|null $has_recording_prompt\n * @property bool $is_internal\n * @property int $is_locked\n * @property int $is_recording\n * @property bool|null $is_processed\n * @property bool $is_private\n * @property bool $is_instant_invite\n * @property string|null $poster_path\n * @property string|null $summary\n * @property string|null $title\n * @property string|null $description\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_start_time\n * @property \\Illuminate\\Support\\Carbon|null $scheduled_end_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_start_time\n * @property \\Illuminate\\Support\\Carbon|null $actual_end_time\n * @property int|null $uploaded_by\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property string|null $average_score\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $activeParticipants\n * @property-read int|null $active_participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers\n * @property-read int|null $activity_scorecard_rule_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Scorecard\\ActivityScorecardRule> $activityScorecardRules\n * @property-read int|null $activity_scorecard_rules_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, AvailabilityNotification> $availabilityNotifications\n * @property-read int|null $availability_notifications_count\n * @property-read \\Jiminny\\Models\\PlaybookCategory|null $category\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, CoachRequest> $coachRequests\n * @property-read int|null $coach_requests_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $coachingFeedbacks\n * @property-read int|null $coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $coachingMessages\n * @property-read int|null $coaching_messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $comments\n * @property-read int|null $comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Connection> $connections\n * @property-read int|null $connections_count\n * @property-read Configuration|null $crm\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, FieldData> $data\n * @property-read int|null $data_count\n * @property-read \\Jiminny\\Models\\Device|null $device\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $favoritePlaylists\n * @property-read int|null $favorite_playlists_count\n * @property-read \\Jiminny\\Models\\Participant|null $from\n * @property-read string|null $activity_title\n * @property-read mixed $comment_count\n * @property-read mixed $duration_for_humans\n * @property-read string $duration_for_humans_short\n * @property-read int $favorite_count\n * @property-read mixed $favorites_count\n * @property-read mixed $formatted_value\n * @property-read string $id_string\n * @property-read \\Jiminny\\Models\\Participant|null $organizer\n * @property-read mixed $play_count\n * @property-read int|null $plays_count\n * @property-read ?ProspectInterface $prospect\n * @property-read string|null $prospect_name\n * @property-read mixed $prospect_type\n * @property-read mixed $share_count\n * @property-read int|null $shares_count\n * @property-read int|null $tracks_with_telephony_count\n * @property-read int|null $visible_comments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\CoachingFeedback> $latestCoachingFeedbacks\n * @property-read int|null $latest_coaching_feedbacks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Log> $logs\n * @property-read int|null $logs_count\n * @property-read \\Jiminny\\Models\\Track|null $masterTrack\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Message> $messages\n * @property-read int|null $messages_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Moment> $moments\n * @property-read int|null $moments_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Note> $notes\n * @property-read int|null $notes_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\Share> $participantShares\n * @property-read int|null $participant_shares_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, ParticipantSpeech> $participantSpeeches\n * @property-read int|null $participant_speeches_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant\\ParticipantStats> $participantStats\n * @property-read int|null $participant_stats_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Participant> $participants\n * @property-read int|null $participants_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, PlaylistActivity> $playlistActivities\n * @property-read int|null $playlist_activities_count\n * @property-read \\Kalnoy\\Nestedset\\Collection<int, \\Jiminny\\Models\\Playlist> $playlists\n * @property-read int|null $playlists_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Play> $plays\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Question> $questions\n * @property-read int|null $questions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Session> $sessions\n * @property-read int|null $sessions_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Share> $shares\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Snapshot> $snapshots\n * @property-read int|null $snapshots_count\n * @property-read Stats|null $stats\n * @property-read \\Jiminny\\Models\\Participant|null $to\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, TopicTrigger> $topicTriggers\n * @property-read int|null $topic_triggers_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracks\n * @property-read int|null $tracks_count\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, \\Jiminny\\Models\\Track> $tracksWithTelephony\n * @property-read Transcription|null $transcription\n * @property-read \\Jiminny\\Models\\User $user\n * @property-read \\Illuminate\\Database\\Eloquent\\Collection<int, Comment> $visibleComments\n *\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> all($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n * @method static \\Database\\Factories\\ActivityFactory factory(...$parameters)\n * @method static \\Illuminate\\Database\\Eloquent\\Collection<int, static> get($columns = ['*'])\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity heldBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity idOrUuId($idOrUuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newModelQuery()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity newQuery()\n * @method static Builder|Activity onlyTrashed()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity query()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity scheduledBetween(\\Carbon\\Carbon $start, \\Carbon\\Carbon $end)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity inOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity notInOpenDeals()\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity forTeam(int $teamId)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity uuid(string $uuid, bool $first = true)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAccountId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereActualStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereAverageScore($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCalendarEventId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereContactId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCreatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmConfigurationId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereCrmProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeletedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDescription($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDeviceId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereDuration($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereFromParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereHasRecordingPrompt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInstantInvite($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsInternal($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsLocked($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsPrivate($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsProcessed($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereIsRecording($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLanguage($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLeadId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLocation($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereLogReminderSentAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOnAir($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOpportunityId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereOrganizerNotifiedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePlaybookCategoryId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity wherePosterPath($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereProvider($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingPreference($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingReasonCode($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereRecordingState($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledEndTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereScheduledStartTime($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSource($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereExternalId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStageId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereStatus($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummary($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereSummaryReminderSent($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTelephonyProviderId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTitle($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereToParticipantId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereTranscriptionId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereType($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUpdatedAt($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUploadedBy($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUserId($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereUuid($value)\n * @method static \\Jiminny\\Component\\Eloquent\\Builder|Activity whereValue($value)\n * @method static Builder|Activity withTrashed()\n * @method static Builder|Activity withoutTrashed()\n *\n * @mixin \\Eloquent\n */\nclass Activity extends Model implements\n ElasticSearch\\Contract\\Searchable,\n Workflow\\Workflow\\WorkflowAwareInterface,\n Models\\Contracts\\ActivityContract,\n Contracts\\Model\\ActivityInterface,\n UuidAwareInterface\n{\n use HasFactory;\n\n use Enums;\n use SoftDeletes;\n use RequiresUUID;\n use BitwiseFlagTrait;\n use ElasticSearch\\Model\\Searchable;\n use ActivityElasticSearchTrait;\n\n use Workflow\\Workflow\\WorkflowAware {\n transitionTo as traitTransitionTo;\n }\n\n public const int FLAG_RECORDING_REASON_DEFAULT = 0;\n\n // Recording Prompted but never started\n public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;\n public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;\n\n // Recording Disabled by Organization\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;\n\n // Recording was restricted to one-side recordings only\n public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;\n\n // Recording was not started because it was internal and team setting disabled that.\n public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;\n\n // Recording was not started because it was internal and user setting disabled that.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;\n\n // Recording was not started because user setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;\n\n // Recording was not started because team setting disabled automatic recording.\n public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;\n\n // Recording was not started because user has overriden default.\n public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;\n\n // Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.\n public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;\n\n // Recording was not started because their team setting does excludes the meeting type.\n public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;\n\n // Recording was not started because the external provider disabled it (or recording is missing etc).\n public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;\n\n // Recording was stopped externally (\"exit-meeting\" Pusher event)\n public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;\n\n // Recording couldn't be started due to Zoom hosting conflict error\n public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;\n\n // meeting.failed event with reason code BOT_DENIED_FROM_LOBBY\n public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;\n\n // meeting.failed event with reason code LOBBY_TIMEOUT\n public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;\n\n // meeting.failed event with reason code BOT_KICKED\n public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;\n\n // meeting.failed event with reason code UNKNOWN\n public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;\n\n public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;\n\n // Invalid meeting (e.g. URL is invalid, or the meeting is not found)\n public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;\n\n // The host stopped the recording.\n public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;\n\n // Recording was not started because an alternative vendor disabled it (or overrode it).\n public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;\n\n // Login required meeting.failed code\n public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;\n\n // Password for meeting was not provided - meeting.failed code\n public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;\n\n // meeting.failed - when the meeting is locked\n public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;\n\n // max recording duration reached\n public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;\n\n // recording size is too small\n public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;\n\n // meeting.failed - when bot is redirected to sign in page multiple times\n public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;\n\n // meeting.failed event with reason code CONNECTION_LOST\n public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;\n\n // recording is corrupted.\n public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;\n\n // meeting ended in lobby\n public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;\n\n // meeting not started\n public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;\n\n // unfinished zoom custom disclaimer\n public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;\n\n // recording download failed - server error\n public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;\n\n // recording download failed - client code 404\n public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;\n\n // recording download failed - client code 401, 403\n public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;\n\n // recording download failed - client code 429\n public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;\n\n // recording download failed - unknown client error\n public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;\n\n // recording download failed - unknown error\n public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;\n\n // It has been setup ahead of time through calendar\n public const string STATUS_SCHEDULED = 'scheduled';\n\n // It is awaiting audio.\n public const string STATUS_PENDING = 'pending';\n\n // Participant(s) dialed in, awaiting organizer.\n public const string STATUS_RINGING = 'ringing';\n\n // Call is in progress.\n public const string STATUS_IN_PROGRESS = 'in-progress';\n\n // It has ended.\n public const string STATUS_COMPLETED = 'completed';\n\n // Cancelled prior to starting.\n public const string STATUS_CANCELLED = 'canceled';\n\n public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference\n\n public const string STATUS_STARTING_SOON = 'starting-soon';\n\n public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';\n\n public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';\n\n public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';\n\n // When bot instance is waiting in lobby\n public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';\n\n public const string STATUS_BUSY = 'busy';\n public const string STATUS_NO_ANSWER = 'no-answer';\n public const string STATUS_FAILED = 'failed'; // Used by SMS too\n\n // SMS related\n public const string STATUS_ACCEPTED = 'accepted';\n public const string STATUS_QUEUED = 'queued';\n public const string STATUS_SENDING = 'sending';\n public const string STATUS_SENT = 'sent';\n public const string STATUS_DELIVERED = 'delivered';\n public const string STATUS_UNDELIVERED = 'undelivered';\n public const string STATUS_RECEIVING = 'receiving';\n public const string STATUS_RECEIVED = 'received';\n public const string STATUS_RESENT = 'resent';\n\n public const array SMS_STATUSES = [\n Activity::STATUS_RECEIVED,\n Activity::STATUS_SENT,\n Activity::STATUS_DELIVERED,\n ];\n\n public const array SOFT_PHONE_CONFERENCE_STATUSES = [\n Activity::STATUS_IN_PROGRESS,\n Activity::STATUS_COMPLETED,\n ];\n\n // @todo refactor prefix from `TYPE_` to `CHANNEL_`\n public const string TYPE_SOFTPHONE = 'softphone';\n public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';\n public const string TYPE_CONFERENCE = 'conference';\n public const string TYPE_SMS_INBOUND = 'sms-inbound';\n public const string TYPE_SMS_OUTBOUND = 'sms-outbound';\n public const string TYPE_EMAIL_INBOUND = 'email-inbound';\n public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';\n\n public const array CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n public const array PLAYABLE_CHANNELS = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n ];\n\n // Recording States\n public const string RECORDING_OFF = 'off'; // Default state\n public const string RECORDING_IN_PROGRESS = 'in-progress';\n public const string RECORDING_PAUSED = 'paused';\n public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.\n public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.\n public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.\n\n // Live Stream States\n public const int ON_AIR_DEFAULT = 0;\n public const int ON_AIR_READY = 1;\n public const int ON_AIR_PREPARING = 2;\n public const int ON_AIR_STREAMING = 3;\n public const int ON_AIR_FINISHED = 4;\n public const int ON_AIR_NOT_STREAMED = 5;\n public const int ON_AIR_ERROR = -1;\n\n public const string SOURCE_GONG = 'gong';\n public const string SOURCE_CHORUS = 'chorus';\n public const string SOURCE_OUTLOOK = 'outlook';\n public const string SOURCE_GOOGLE = 'google';\n\n // Activity Providers\n public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.\n public const string PROVIDER_OUTREACH = 'outreach';\n public const string PROVIDER_ZOOM_BOT = 'zoom-bot';\n public const string PROVIDER_SALESLOFT = 'salesloft';\n public const string PROVIDER_GOOGLE = 'google';\n public const string PROVIDER_AIRCALL = 'aircall';\n public const string PROVIDER_JUSTCALL = 'justcall';\n public const string PROVIDER_GOOGLE_MEET = 'google-meet';\n public const string PROVIDER_GONG = 'gong';\n public const string PROVIDER_HUBSPOT = 'hubspot';\n public const string PROVIDER_CLOSE = 'close';\n public const string PROVIDER_TEAMS = 'ms-teams';\n public const string PROVIDER_SALESFORCE = 'salesforce';\n public const string PROVIDER_GROOVE = 'groove';\n public const string PROVIDER_XANT = 'xant';\n public const string PROVIDER_OFFICE = 'office';\n public const string PROVIDER_NATTERBOX = 'natterbox';\n public const string PROVIDER_RINGCENTRAL = 'ringcentral';\n public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';\n public const string PROVIDER_GOTOMEETING = 'go-to-meeting';\n public const string PROVIDER_DEMODESK = 'demo-desk';\n public const string PROVIDER_DIALPAD = 'dialpad';\n public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';\n public const string PROVIDER_CLOUDCALL = 'cloudcall';\n public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';\n public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // \"8x8\" UK\n public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // \"8x8\" Canada\n public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // \"8x8\" Australia\n public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // \"8x8\" US East\n public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // \"8x8\" US West\n public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';\n public const string PROVIDER_CLOUD_TALK = 'cloud-talk';\n public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';\n public const string PROVIDER_VONAGE = 'vonage';\n public const string PROVIDER_MIGRATOR = 'migrator';\n public const string PROVIDER_UPLOADER = 'uploader';\n public const string PROVIDER_TALKDESK = 'talkdesk';\n public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';\n public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';\n public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';\n public const string PROVIDER_AVAYA = 'avaya';\n public const string PROVIDER_TELUS = 'telus';\n public const string PROVIDER_FIVE_NINE = 'five-nine';\n public const string PROVIDER_APOLLO = 'apollo';\n public const string PROVIDER_ORUM = 'orum';\n public const string PROVIDER_BLOOBIRDS = 'bloobirds';\n\n /**\n * @const API_PROVIDERS\n * A list of integrations that import calls via API instead of webhooks\n */\n public const array API_PROVIDERS = [\n self::PROVIDER_OUTREACH,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n ];\n\n public const array FINITE_STATES = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_NO_ANSWER,\n self::STATUS_BUSY,\n ],\n self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,\n ];\n\n public const array FINITE_STATES_CONFERENCE = [\n self::STATUS_COMPLETED,\n self::STATUS_FAILED,\n self::STATUS_CANCELLED,\n ];\n\n public const array MEETING_BOT_JOIN_ATTEMPTED = [\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_BOT_INSTANCE_STARTED,\n ];\n\n public static array $enumStatuses = [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_ACCEPTED,\n self::STATUS_QUEUED,\n self::STATUS_SENDING,\n self::STATUS_SENT,\n self::STATUS_RESENT,\n self::STATUS_DELIVERED,\n self::STATUS_UNDELIVERED,\n self::STATUS_RECEIVING,\n self::STATUS_RECEIVED,\n self::STATUS_BOT_INSTANCE_WAITING_LOBBY,\n self::STATUS_STARTING_SOON,\n self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,\n self::STATUS_BOT_INSTANCE_STARTED,\n self::STATUS_DUPLICATED,\n ];\n\n public static array $enumProviders = [\n self::PROVIDER_TWILIO,\n self::PROVIDER_OUTREACH,\n self::PROVIDER_ZOOM_BOT,\n self::PROVIDER_SALESLOFT,\n self::PROVIDER_AIRCALL,\n self::PROVIDER_JUSTCALL,\n self::PROVIDER_GOOGLE_MEET,\n self::PROVIDER_GONG,\n self::PROVIDER_HUBSPOT,\n self::PROVIDER_CLOSE,\n self::PROVIDER_TEAMS,\n self::PROVIDER_SALESFORCE,\n self::PROVIDER_GROOVE,\n self::PROVIDER_XANT,\n self::PROVIDER_GOOGLE,\n self::PROVIDER_OFFICE,\n self::PROVIDER_NATTERBOX,\n self::PROVIDER_RINGCENTRAL,\n self::PROVIDER_RINGCENTRAL_VIDEO,\n self::PROVIDER_GOTOMEETING,\n self::PROVIDER_DEMODESK,\n self::PROVIDER_DIALPAD,\n self::PROVIDER_ZOOM_PHONE,\n self::PROVIDER_CLOUDCALL,\n self::PROVIDER_CLOUDCALL_US,\n self::PROVIDER_EIGHT_BY_EIGHT,\n self::PROVIDER_EIGHT_BY_EIGHT_CA,\n self::PROVIDER_EIGHT_BY_EIGHT_AP,\n self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,\n self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,\n self::PROVIDER_CONNECT_AND_SELL,\n self::PROVIDER_CLOUD_TALK,\n self::PROVIDER_AMAZON_CONNECT,\n self::PROVIDER_VONAGE,\n self::PROVIDER_TALKDESK,\n self::PROVIDER_TWILIO_FLEX,\n self::PROVIDER_TWILIO_FLEX_DIRECT,\n self::PROVIDER_TWILIO_VIDEO,\n self::PROVIDER_AVAYA,\n self::PROVIDER_TELUS,\n self::PROVIDER_FIVE_NINE,\n self::PROVIDER_APOLLO,\n self::PROVIDER_ORUM,\n self::PROVIDER_BLOOBIRDS,\n ];\n\n public static $enumRecordingStates = [\n self::RECORDING_OFF, // Default state\n self::RECORDING_IN_PROGRESS,\n self::RECORDING_PAUSED,\n self::RECORDING_STOPPED,\n self::RECORDING_RECORDED,\n self::RECORDING_FAILED,\n ];\n\n // @Important:\n // This collection is not used anywhere, and is fully duplicated by the Channels const.\n // Validate if it is referred somehow via the enum trait, and if not, remove it entirely.\n // An even better strategy will be to move all those constants to a dedicated class\n protected array $enumTypes = [\n self::TYPE_SOFTPHONE,\n self::TYPE_SOFTPHONE_INBOUND,\n self::TYPE_CONFERENCE,\n self::TYPE_SMS_INBOUND,\n self::TYPE_SMS_OUTBOUND,\n self::TYPE_EMAIL_INBOUND,\n self::TYPE_EMAIL_OUTBOUND,\n ];\n\n protected static $enumFailedStatuses = [\n self::STATUS_NO_ANSWER,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n self::STATUS_CANCELLED,\n ];\n\n protected $table = 'activities';\n\n protected $fillable = [\n // Type of activity.\n 'type', // @todo refactor to `channel`\n // The activity type.\n 'playbook_category_id',\n // User who hosts the activity.\n 'user_id',\n // Related Lead record (if applicable)\n 'lead_id',\n // Related Account record (if applicable)\n 'account_id',\n // Related Contact record (if applicable)\n 'contact_id',\n // Related Opportunity record (if applicable)\n 'opportunity_id',\n // Stage of activity.\n 'stage_id',\n // Value of opportunity.\n 'value',\n // If the activity relates to a CRM task.\n 'crm_provider_id',\n // If the activity was created through an external device.\n 'device_id',\n // the activity's language code\n 'language',\n // transcription id\n 'transcription_id',\n // Duration of the call, with microseconds precision.\n 'duration',\n // One of enumStatuses above.\n 'status',\n // Have we reminded them to log the call?\n 'log_reminder_sent_at',\n // If activity is private or inter-org, flagged here.\n 'is_internal',\n // Managers and above can mark a call as private, to exclude it from other team members\n 'is_private',\n 'is_processed',\n // Boolean for this activity being instant invite handled.\n 'is_instant_invite',\n // If activity is in recording state, flagged here.\n 'recording_state',\n // If activity recording is overidden from default.\n 'recording_preference',\n // if recording did (not) happen, why that is\n 'recording_reason_code',\n // Average score, updated during\n 'average_score',\n // Summary that the organizer has taken after the call.\n 'summary',\n // Subject of the activity, usually taken from calendar event.\n 'title',\n // Description of the activity, usually taken from calendar event.\n 'description',\n // Start time, usually taken from calendar event.\n 'scheduled_start_time',\n // End time, usually taken from calendar event.\n 'scheduled_end_time',\n // When the call actually started.\n 'actual_start_time',\n // When the call actually ended.\n 'actual_end_time',\n // SMS: Message reference\n 'telephony_provider_id',\n // SMS: Participant who sent message\n 'from_participant_id',\n // SMS: Participant who should receive the message\n 'to_participant_id',\n // When an external guest joins an organizers meeting room and the organizer is not present,\n // send them an SMS notification that someone has joined.\n 'organizer_notified_at',\n // where was the activity imported from\n 'source',\n // The id in the source system (e.g. the bot id in Recall.ai)\n 'external_id',\n // The provider, by default it is twilio.\n 'provider',\n // Meeting location url\n 'location',\n // The snapshot for displaying a poster image.\n 'poster_path',\n 'crm_configuration_id',\n // If there is an automated message that the conversation is being recorded\n 'has_recording_prompt',\n // If the activity is being live-streamed\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected $appends = [\n 'id_string',\n 'organizer',\n ];\n\n protected $hidden = [\n 'uuid',\n ];\n\n protected $visible = [\n 'id_string',\n 'type',\n 'duration',\n 'average_score',\n 'status',\n 'log_reminder_sent_at',\n 'title',\n 'description',\n 'is_internal',\n 'scheduled_start_time',\n 'scheduled_end_time',\n 'actual_start_time',\n 'actual_end_time',\n 'user',\n 'category',\n 'account',\n 'contact',\n 'opportunity',\n 'lead',\n 'stage',\n 'stats',\n 'participants',\n 'playlists',\n 'tracks',\n 'comments',\n 'plays',\n 'coachingFeedbacks',\n 'shares',\n 'favorites',\n 'language',\n 'transcription',\n 'is_private',\n 'is_instant_invite',\n 'on_air',\n 'calendar_event_id',\n ];\n\n protected function casts(): array\n {\n return [\n 'scheduled_start_time' => 'datetime',\n 'scheduled_end_time' => 'datetime',\n 'actual_start_time' => 'datetime',\n 'actual_end_time' => 'datetime',\n 'organizer_notified_at' => 'datetime',\n 'log_reminder_sent_at' => 'datetime',\n 'is_internal' => 'boolean',\n 'duration' => 'integer',\n 'average_score' => 'decimal:2',\n 'is_private' => 'boolean',\n 'is_processed' => 'boolean',\n 'is_instant_invite' => 'boolean',\n 'value' => 'decimal:2',\n 'recording_preference' => 'boolean',\n 'recording_reason_code' => 'integer',\n 'has_recording_prompt' => 'boolean',\n 'on_air' => 'integer',\n ];\n }\n\n protected static function boot()\n {\n parent::boot();\n\n static::updated(static function (Activity $activity) {\n // If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week\n if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||\n ($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {\n if ($activity->isDirty('status')) {\n event(new StatusUpdated($activity));\n }\n\n if ($activity->isDirty('stage_id')) {\n event(new StageUpdated($activity));\n }\n\n if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {\n event(new ProspectUpdated($activity));\n }\n\n if ($activity->isDirty('opportunity_id')) {\n event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));\n }\n\n if ($activity->isDirty('title')) {\n event(new TitleUpdated($activity));\n }\n }\n\n if ($activity->isDirty('playbook_category_id')) {\n event(new ActivityTypeUpdated($activity));\n }\n });\n\n static::deleted(static function (Activity $activity) {\n // Hard delete associated playlistActivities\n $activity->playlistActivities()->delete();\n });\n }\n\n public function getOrganizerAttribute(): ?Participant\n {\n $participant = $this->participants()->where('user_id', $this->user_id)->first();\n\n if (! $participant instanceof Participant && $participant !== null) {\n throw new RuntimeException(sprintf('$participant must be an instance of \"%s\" or null', Participant::class));\n }\n\n return $participant;\n }\n\n public function getFormattedValueAttribute()\n {\n $currencyCode = 'USD';\n if ($this->opportunity) {\n $currencyCode = $this->opportunity->getCurrencyCode();\n }\n\n $formatter = new CurrencyFormatter();\n $formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);\n $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);\n\n return $formatter->format($this->value, $currencyCode);\n }\n\n public function getProspectNameAttribute(): ?string\n {\n $prospectName = null;\n\n if ($this->lead_id) {\n $prospectName = $this->lead->name;\n } elseif ($this->contact_id) {\n $prospectName = $this->contact->name;\n } elseif ($this->account_id) {\n $prospectName = $this->account->name;\n }\n\n return $prospectName;\n }\n\n public function getProspectName(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('prospect_name');\n }\n\n /**\n * Get activity title depending on prospect or title\n */\n public function getActivityTitleAttribute(): ?string\n {\n $activityTitle = null;\n if ($this->prospect && $this->prospect->getName()) {\n if ($this->account_id) {\n $activityTitle = $this->account->name;\n } elseif ($this->lead_id) {\n $activityTitle = $this->lead->company;\n } elseif ($this->contact_id) {\n $activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;\n }\n } elseif ($this->title) {\n $activityTitle = $this->title;\n }\n\n return $activityTitle;\n }\n\n public function wasRecentlyCreated(): bool\n {\n return $this->wasRecentlyCreated;\n }\n\n public function getProspectTypeAttribute()\n {\n $prospectType = null;\n\n if ($this->lead_id) {\n $prospectType = 'Lead';\n } elseif ($this->contact_id) {\n $prospectType = 'Contact';\n } elseif ($this->account_id) {\n $prospectType = 'Account';\n }\n\n return $prospectType;\n }\n\n /**\n * Return the best match for prospect. Results are in the following order of priority:\n * 1. Lead\n * 2. Contact\n * 3. Account\n * 4. NULL\n */\n public function getProspectAttribute(): ?ProspectInterface\n {\n if ($this->hasLead()) {\n return $this->getLead();\n }\n\n if ($this->hasContact()) {\n return $this->getContact();\n }\n\n if ($this->hasAccount()) {\n return $this->getAccount();\n }\n\n return null;\n }\n\n public function getTitleAttribute($value): ?string\n {\n return \\getActivityTitleAttribute(\n $this->user->name,\n $this->getType(),\n $value,\n $this->prospect->name ?? null,\n $this->from->national_phone_number ?? null\n );\n }\n\n public function getTitle(): ?string\n {\n return $this->getAttribute('title');\n }\n\n public function getSummary(): ?string\n {\n return $this->getAttribute('summary');\n }\n\n public function isInternal(): bool\n {\n return $this->getAttribute('is_internal');\n }\n\n public function getIsPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n public function getDescription(): ?string\n {\n return $this->getAttribute('description');\n }\n\n public function hasTitle(): bool\n {\n return $this->getOriginal('title') !== null;\n }\n\n public function getPlayCountAttribute()\n {\n return $this->getPlaysCountAttribute();\n }\n\n public function getPlaysCountAttribute()\n {\n if (! isset($this->attributes['plays_count'])) {\n $this->loadCount('plays');\n }\n\n return $this->attributes['plays_count'];\n }\n\n public function getCommentCountAttribute()\n {\n return $this->getCommentsCountAttribute();\n }\n\n public function getCommentsCountAttribute()\n {\n if (! isset($this->attributes['comments_count'])) {\n $this->loadCount('comments');\n }\n\n return $this->attributes['comments_count'];\n }\n\n public function getVisibleCommentsCountAttribute()\n {\n if (! isset($this->attributes['visible_comments_count'])) {\n $activityCommentsService = app(ActivityCommentService::class);\n $user = Auth::user() instanceof User ? Auth::user() : null;\n $this->attributes['visible_comments_count'] = $activityCommentsService\n ->getVisibleCommentsCount($this, $user);\n }\n\n return $this->attributes['visible_comments_count'];\n }\n\n public function getShareCountAttribute()\n {\n return $this->getSharesCountAttribute();\n }\n\n public function getSharesCountAttribute()\n {\n if (! isset($this->attributes['shares_count'])) {\n $this->loadCount('shares');\n }\n\n return $this->attributes['shares_count'];\n }\n\n\n /**\n * Get the count of favorites playlists this activity appears in\n */\n public function getFavoriteCountAttribute(): int\n {\n return $this->getFavoritesCountAttribute();\n }\n\n public function getFavoritesCountAttribute()\n {\n if (! isset($this->attributes['favorites_count'])) {\n $this->loadCount('favorites');\n }\n\n return $this->attributes['favorites_count'];\n }\n\n public function getActiveParticipantsCountAttribute()\n {\n if (! isset($this->attributes['active_participants_count'])) {\n $this->loadCount('activeParticipants');\n }\n\n return $this->attributes['active_participants_count'];\n }\n\n public function getTracksWithTelephonyCountAttribute()\n {\n if (! isset($this->attributes['tracks_with_telephony_count'])) {\n $this->loadCount('tracksWithTelephony');\n }\n\n return $this->attributes['tracks_with_telephony_count'];\n }\n\n /**\n * @TEMP\n * $this->loadCount('tracksWithTelephony') throws null pointer exception\n */\n public function countTracksWithTelephony(): int\n {\n return $this->tracks()->whereNotNull('telephony_provider_id')->count();\n }\n\n public function getDuration(): float\n {\n return $this->getAttribute('duration');\n }\n\n public function getDurationForHumansAttribute()\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);\n }\n\n public function getDurationForHumansShortAttribute(): string\n {\n return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);\n }\n\n public function hasRecordingPreference(): bool\n {\n return $this->getAttribute('recording_preference') !== null;\n }\n\n public function getRecordingPreference()\n {\n return $this->getAttribute('recording_preference');\n }\n\n /** @return BelongsTo<User, self> */\n public function user(): BelongsTo\n {\n return $this->belongsTo(User::class)->with('group');\n }\n\n public function device()\n {\n return $this->belongsTo(Device::class);\n }\n\n public function category()\n {\n return $this->belongsTo(PlaybookCategory::class, 'playbook_category_id');\n }\n\n public function getCategory(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function getPlaybookCategoryId(): ?int\n {\n return $this->getAttribute('playbook_category_id');\n }\n\n public function hasStats(): bool\n {\n return $this->getAttribute('stats') !== null;\n }\n\n public function getStats(): ?Stats\n {\n return $this->getAttribute('stats');\n }\n\n public function stats(): HasOne\n {\n return $this->hasOne(Stats::class);\n }\n\n public function participantStats(): Eloquent\\Relations\\HasManyThrough\n {\n return $this->hasManyThrough(\n Models\\Participant\\ParticipantStats::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantStats(): Eloquent\\Collection\n {\n return $this->getAttribute('participantStats');\n }\n\n public function account()\n {\n return $this->belongsTo(Account::class);\n }\n\n public function contact()\n {\n return $this->belongsTo(Contact::class)->with(['account']);\n }\n\n public function lead()\n {\n return $this->belongsTo(Lead::class)->with(['stage', 'recordType']);\n }\n\n /**\n * @return BelongsTo<Opportunity, self>\n */\n public function opportunity(): BelongsTo\n {\n /** @var BelongsTo<Opportunity, self> */\n return $this->belongsTo(Opportunity::class);\n }\n\n public function stage()\n {\n return $this->belongsTo(Stage::class);\n }\n\n /**\n * @return HasMany<Session>\n */\n public function sessions(): HasMany\n {\n return $this->hasMany(Session::class);\n }\n\n /**\n * @return HasMany|ParticipantSpeech[]|Eloquent\\Collection\n */\n public function participantSpeeches()\n {\n return $this->hasMany(ParticipantSpeech::class);\n }\n\n public function getParticipantSpeeches(): Eloquent\\Collection\n {\n return $this->getAttribute('participantSpeeches');\n }\n\n /**\n * @return HasMany|Log[]|Eloquent\\Collection\n */\n public function logs()\n {\n return $this->hasMany(Log::class);\n }\n\n /**\n * @return HasMany|Moment[]|Eloquent\\Collection\n */\n public function moments()\n {\n return $this->hasMany(Moment::class);\n }\n\n /**\n * @return HasMany|Note[]|Eloquent\\Collection\n */\n public function notes()\n {\n return $this->hasMany(Note::class);\n }\n\n /**\n * @return Eloquent\\Collection|Note[]\n */\n public function getNotes(): Eloquent\\Collection\n {\n return $this->getAttribute('notes');\n }\n\n /**\n * @return HasMany|Message[]|Eloquent\\Collection\n */\n public function messages()\n {\n return $this->hasMany(Message::class);\n }\n\n public function coachingMessages(): HasMany\n {\n return $this->hasMany(Message::class)\n ->where('is_private', 1);\n }\n\n public function getCoachingMessages(): Eloquent\\Collection\n {\n return $this->getAttribute('coachingMessages');\n }\n\n public function participants(): HasMany\n {\n return $this->hasMany(Participant::class);\n }\n\n public function getSnapshots(): Eloquent\\Collection\n {\n return $this->getAttribute('snapshots');\n }\n\n /** @return HasMany<Track> */\n public function tracks(): HasMany\n {\n return $this->hasMany(Track::class);\n }\n\n public function tracksWithTelephony(): HasMany\n {\n return $this->hasMany(Track::class)->whereNotNull('telephony_provider_id');\n }\n\n public function getTracksWithTelephony(): Eloquent\\Collection\n {\n return $this->getAttribute('tracksWithTelephony');\n }\n\n /** @return Collection|Track[] */\n public function getTracks(): Eloquent\\Collection\n {\n return $this->getAttribute('tracks');\n }\n\n public function masterTrack(): HasOne\n {\n return $this->hasOne(Track::class)->where('is_master', 1)\n ->whereIn('format', [Track::FORMAT_WAV, Track::FORMAT_M3U8])\n ->latest();\n }\n\n public function getMasterTrack(): ?Track\n {\n /** @var Track|null */\n return $this->getAttribute('masterTrack');\n }\n\n public function transcription(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Transcription::class, 'transcription_id');\n }\n\n public function findTranscriptionPromptSummaries(): Collection\n {\n $transcriptionId = $this->getTranscriptionId();\n if (is_null($transcriptionId)) {\n return new Collection();\n }\n\n return Models\\AiPrompt::query()\n ->where('transcription_id', $transcriptionId)\n ->get();\n }\n\n public function getTranscription(): Transcription\n {\n return $this->getAttribute('transcription');\n }\n\n public function hasTranscription(): bool\n {\n return $this->getAttribute('transcription') !== null;\n }\n\n public function setTranscriptionId(int $transcriptionId): Activity\n {\n $this->setAttribute('transcription_id', $transcriptionId);\n\n return $this;\n }\n\n public function unsetTranscriptionId(): self\n {\n $this->setAttribute('transcription_id', null);\n\n return $this;\n }\n\n public function getTranscriptionId(): ?int\n {\n return $this->getAttribute('transcription_id');\n }\n\n /** @deprecated */\n public function hasTranscriptionId(): bool\n {\n return $this->getAttribute('transcription_id') !== null;\n }\n\n public function coachRequests()\n {\n return $this->hasMany(CoachRequest::class);\n }\n\n public function availabilityNotifications()\n {\n return $this->hasMany(AvailabilityNotification::class);\n }\n\n public function processingStates()\n {\n return $this->hasMany(Models\\Activity\\ActivityProcessingState::class);\n }\n\n public function uploadSettings()\n {\n return $this->hasMany(ActivityUploadSetting::class);\n }\n\n public function comments()\n {\n return $this->hasMany(Comment::class);\n }\n\n public function getComments(): Eloquent\\Collection\n {\n return $this->getAttribute('comments');\n }\n\n public function visibleComments()\n {\n $rel = $this->hasMany(Comment::class);\n // Doesn't have auth()->user() in some tests, breaks the build\n if ($user = auth()->user()) {\n return $rel->visibleThreads($user->id);\n }\n\n return $rel;\n }\n\n public function snapshots(): HasMany\n {\n return $this->hasMany(Snapshot::class);\n }\n\n public function calendarEvent()\n {\n return $this->belongsTo(CalendarEvent::class);\n }\n\n public function getCalendarEvent(): ?CalendarEvent\n {\n return $this->getAttribute('calendarEvent');\n }\n\n public function latestCoachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class)->latest();\n }\n\n public function playlists(): BelongsToMany\n {\n return $this->belongsToMany(Playlist::class, 'playlist_activities')\n ->withPivot('id', 'uuid', 'user_id', 'start_time', 'end_time')\n ->using(PlaylistActivity::class)\n ->withTimestamps();\n }\n\n public function coachingFeedbacks(): HasMany\n {\n return $this->hasMany(CoachingFeedback::class);\n }\n\n /**\n * @return Eloquent\\Collection|CoachingFeedback[]\n */\n public function getCoachingFeedback(?int $visibility = null): Eloquent\\Collection\n {\n $feedbacks = $this->coachingFeedbacks();\n if ($visibility !== null) {\n $feedbacks = $feedbacks->where('visibility', $visibility);\n }\n\n return $feedbacks->get();\n }\n\n /** @return Eloquent\\Collection<int, PlaylistActivity> */\n public function favoritedBy(User $user): Eloquent\\Collection\n {\n return $this->favorites()->where('user_id', $user->getId())->get();\n }\n\n /**\n * Checks whether consumer has added this activity to their favorites playlist\n * In addition a default playlist gets created if not already present\n */\n public function wasFavoritedBy(User $user): bool\n {\n $playlist = $user->favoritePlaylist();\n\n return $playlist\n ->activities()\n ->where('activity_id', '=', $this->getId())\n ->exists();\n }\n\n /**\n * @return HasMany<PlaylistActivity>\n */\n public function playlistActivities(): HasMany\n {\n return $this->hasMany(PlaylistActivity::class);\n }\n\n /**\n * @return HasManyThrough<Playlist>\n */\n public function favoritePlaylists(): HasManyThrough\n {\n return $this->hasManyThrough(\n Playlist::class,\n PlaylistActivity::class,\n 'activity_id',\n 'id',\n 'id',\n 'playlist_id'\n )->where('is_default', 1);\n }\n\n /**\n * @return Eloquent\\Collection<int, Playlist>\n */\n public function getFavoritePlaylists(): Eloquent\\Collection\n {\n return $this->getAttribute('favoritePlaylists');\n }\n\n /**\n * Get activities from the default/favorite playlist\n *\n * @return Eloquent\\Builder|static\n */\n public function favorites()\n {\n return $this->playlistActivities()->whereHas('playlist', function ($query) {\n $query->where('is_default', 1);\n });\n }\n\n /**\n * @return Model|SubscriptionSet|null|object\n */\n public function subscribedBy(User $user)\n {\n if ($this->prospect === null) {\n return null;\n }\n\n return SubscriptionSet::select('activity_subscription_sets.*')\n ->where('user_id', $user->id)\n ->join('activity_subscriptions', function ($join) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $join\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $join\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $join\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $join\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n }\n })\n ->first();\n }\n\n /**\n * @return array|Eloquent\\Builder[]|Eloquent\\Collection|SubscriptionSet[]\n */\n public function subscribers()\n {\n if ($this->prospect === null) {\n return [];\n }\n\n return SubscriptionSet::with(['subscriptions', 'user'])\n ->whereHas('subscriptions', function ($query) {\n if ($this->account_id) {\n if ($this->opportunity_id) {\n $query\n ->where('followable_type', 'opportunity')\n ->where('followable_id', $this->opportunity_id);\n } else {\n $query\n ->where('followable_type', 'account')\n ->where('followable_id', $this->account_id);\n }\n } elseif ($this->contact_id) {\n $query\n ->where('followable_type', 'contact')\n ->where('followable_id', $this->contact_id);\n } elseif ($this->lead_id) {\n $query\n ->where('followable_type', 'lead')\n ->where('followable_id', $this->lead_id);\n } else {\n // Nothing to join on?\n // refactor - use Jiminny specific exception\n throw new InvalidArgumentException('Cannot join on a specific customer filter.');\n }\n })\n ->whereHas('user', function ($query) {\n $query\n ->where('team_id', $this->user->team_id)\n ->where('status', User::STATUS_ACTIVE);\n })\n ->get();\n }\n\n /**\n * @return HasMany|Builder|Eloquent\\Collection|Play[]\n */\n public function plays()\n {\n return $this->hasMany(Play::class);\n }\n\n public function getPlays(): Eloquent\\Collection\n {\n return $this->getAttribute('plays');\n }\n\n public function playsBy(User $user)\n {\n /** @var Builder $builder */\n $builder = $this->plays()->where('user_id', $user->id);\n\n return $builder->get();\n }\n\n /**\n * Check if activity was played by a user\n */\n public function wasPlayedBy(User $user): bool\n {\n return $this->plays()->where('user_id', $user->id)->exists();\n }\n\n public function shares()\n {\n return $this->hasMany(Share::class);\n }\n\n /** @return BelongsTo<Participant, self> */\n public function from(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'from_participant_id');\n }\n\n /** @return BelongsTo<Participant, self> */\n public function to(): BelongsTo\n {\n return $this->belongsTo(Participant::class, 'to_participant_id');\n }\n\n /**\n * Get all of the connections through the participants.\n */\n public function connections()\n {\n return $this->hasManyThrough(\n Connection::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getConnections(): Eloquent\\Collection\n {\n return $this->getAttribute('connections');\n }\n\n /**\n * Get all of the shares through the participants.\n */\n public function participantShares()\n {\n return $this->hasManyThrough(\n Participant\\Share::class,\n Participant::class,\n 'activity_id',\n 'participant_id'\n );\n }\n\n public function getParticipantShares(): Eloquent\\Collection\n {\n return $this->getAttribute('participantShares');\n }\n\n public function topicTriggers(): HasMany\n {\n return $this->hasMany(TopicTrigger::class);\n }\n\n public function activityScorecardRuleTriggers(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRuleTrigger::class);\n }\n\n public function activityScorecardRules(): HasMany\n {\n return $this->hasMany(Models\\Scorecard\\ActivityScorecardRule::class);\n }\n\n public function questions(): HasMany\n {\n return $this->hasMany(Question::class);\n }\n\n /**\n * Get all the custom data attached to it.\n */\n public function data(): HasMany\n {\n return $this->hasMany(FieldData::class);\n }\n\n public function getData(): Eloquent\\Collection\n {\n /** @var Eloquent\\Collection */\n return $this->getAttribute('data');\n }\n\n #[Scope]\n protected function heldBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('actual_start_date', '>=', $from)\n ->where('actual_end_date', '<=', $until);\n }\n\n #[Scope]\n protected function scheduledBetween($query, Carbon $start, Carbon $end)\n {\n // Sanity check.\n $from = min($start, $end);\n $until = max($start, $end);\n\n return $query\n ->where('scheduled_start_date', '>=', $from)\n ->where('scheduled_end_date', '<=', $until);\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function forTeam(Builder $query, int $teamId): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas('user', static function (Builder $query) use ($teamId): void {\n $query->where('team_id', $teamId);\n });\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function inOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->whereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query\n ->where('is_closed', false)\n ->where('deleted_at', '=', null),\n );\n }\n\n /**\n * @param Builder<self> $query\n *\n * @return Builder<self>\n */\n #[Scope]\n protected function notInOpenDeals(Builder $query): Builder\n {\n /** @var Builder<self> */\n return $query->where(\n static fn (Builder $query): Builder => $query->whereNull('opportunity_id')\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->where('is_closed', true),\n )\n ->orWhereHas(\n 'opportunity',\n static fn (Builder $query): Builder => $query->withTrashed()->where('deleted_at', '!=', null),\n ),\n );\n }\n\n /**\n * Finds a participant and updates it with data. If participant doesn't exist creates a new participant from data.\n *\n * @param array $data participant data used to identify the participant and update it\n * @param bool $enterRoom true if participant is entering the room. false if we just want to update some participant data\n * @param Carbon|null $enterTime if $enterNow is true then this is the join time when the actual enter has occurred\n */\n public function updateOrCreateParticipant(\n array $data,\n bool $enterRoom = true,\n ?Carbon $enterTime = null,\n bool $nameMatching = false,\n ): Participant {\n $search = [];\n $participant = null;\n\n if (isset($data['user_id'])) {\n // Check if they already exist based on their ID.\n $search['user_id'] = $data['user_id'];\n } elseif (isset($data['provider_id'])) {\n $search['provider_id'] = $data['provider_id'];\n } elseif ($nameMatching && isset($data['name'])) {\n $search['name'] = $data['name'];\n }\n\n if (! empty($data['email'])) {\n $search['email'] = $data['email'];\n\n // If we have their email, this should be unique enough to lookup (e.g. calendar event based participant).\n unset($search['provider_id']);\n }\n\n // Search by phone number only in case nothing else is available to search by.\n if (array_key_exists('phone_number', $data) && empty($search)) {\n $search['phone_number'] = $data['phone_number'];\n }\n\n if (! empty($search)) {\n // Do a lookup now to see if we have a match on the provided data.\n $lookup = array_map(static function ($key, $value): array {\n return [$key, $value];\n }, array_keys($search), $search);\n\n $participant = $this->participants()->withTrashed()->where($lookup)->first();\n }\n\n // Do a partial match on the name and search in the team members.\n if (! $participant instanceof Participant && $nameMatching && ! empty($data['name'])) {\n $participantMatcher = app(MeetingBot\\Service\\ParticipantMatcher::class);\n\n if (! $participantMatcher instanceof MeetingBot\\Service\\ParticipantMatcher) {\n throw new LogicException('Expecting ParticipantMatcher service instance');\n }\n\n $participant = $participantMatcher->match($this, $data['name']);\n\n // If we've found good participant, avoid data overwrite in `$participant->fill($data)` below.\n if ($participant instanceof Models\\Participant && $participant->hasName()) {\n unset($data['name']); // Thoughts: should we unset also $data['user_id'] and $data['email'] ?\n }\n }\n\n if (! $participant instanceof Participant) {\n // If no match, create a new participant.\n if (empty($search)) {\n $participant = $this->participants()->create();\n } else {\n // If no match, create a new participant but avoid creating duplicates\n $participant = $this->participants()->withTrashed()->firstOrNew($search);\n }\n }\n\n // If we have just recycled a deleted participant\n if ($participant->trashed()) {\n $participant->deleted_at = null;\n }\n\n // Deal with the case when calendar syncs the event while it's in progress.\n // We should prevent change of the participant name, because speeches mapping will fail.\n if ($enterRoom === false\n && $this->isInProgress()\n && $participant->hasName()\n && isset($data['name'])\n && $data['name'] !== $participant->getName()\n ) {\n unset($data['name']);\n }\n\n // Upsert with new data.\n $participant->fill($data);\n\n if ($enterRoom) {\n if ($enterTime === null) {\n $enterTime = now();\n }\n\n // Participant enters room for the first time\n if ($participant->enter_time === null) {\n $participant->enter_time = $enterTime;\n }\n\n // If there is an exit time and it's prior to new enter_time\n if ($participant->exit_time && $participant->exit_time->lt($enterTime)) {\n // Participant has re-joined\n $participant->exit_time = null;\n }\n }\n\n $participant->save();\n\n return $participant;\n }\n\n /**\n * Updates participant CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n * @param Participant $participant participant the CRM data is associated with\n */\n public function updateParticipantCrmData(array $records, Participant $participant): void\n {\n // Extract the records.\n [$lead, , , $contact] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForParticipant($lead, $contact);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n if (! $participant->hasName()) {\n $participant->name = $lead->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $lead->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $lead->phone;\n }\n\n $participant->lead_id = $lead->id;\n $participant->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n if (! $participant->hasName()) {\n $participant->name = $contact->name;\n }\n\n if (! $participant->hasEmailAddress()) {\n $participant->email = $contact->email;\n }\n\n if (! $participant->hasPhoneNumber()) {\n $participant->phone_number = $contact->phone;\n }\n\n $participant->contact_id = $contact->id;\n $participant->save();\n }\n }\n\n /**\n * Updates activity CRM data\n *\n * @param array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *} $records\n */\n public function updateActivityCrmData(array $records): void\n {\n // Extract the records.\n [$lead, $account, $opportunity, $contact, $stage] = $records;\n\n $resolver = $this->getUpdateCrmDataResolver();\n $strategy = $resolver->resolveForActivity($lead, $contact, $account);\n\n if ($strategy == UpdateCrmDataByStrategy::Lead) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n if ($this->account_id === null && $this->contact_id === null && $this->lead_id === null) {\n $this->lead_id = $lead->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n $this->save();\n }\n } elseif ($strategy == UpdateCrmDataByStrategy::Contact) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Don't trust previous matched account_id as it might have been changed in the CRM\n if ($account && $account->id !== $this->account_id) {\n $this->account_id = $account->id;\n }\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($opportunity && $this->opportunity_id !== $opportunity->id) {\n $this->opportunity_id = $opportunity->id;\n }\n\n if ($opportunity && $this->value !== $opportunity->value) {\n $this->value = $opportunity->value;\n }\n\n // Always set contact_id when available, regardless of account_id status\n if ($this->contact_id === null && $contact) {\n $this->contact_id = $contact->id;\n }\n\n $this->save();\n } elseif ($strategy == UpdateCrmDataByStrategy::Account && $this->account_id === null) {\n // Also update the parent activity if required, checking we don't create a mixed lead/account record.\n $this->lead_id = null;\n if ($this->stage && $this->stage->getType() === Stage::TYPE_LEAD) {\n $this->stage_id = null;\n }\n\n // Update the account and opportunity on the activity record if possible.\n $this->account_id = $account->id;\n\n if ($this->stage_id === null && $stage) {\n $this->stage_id = $stage->id;\n }\n\n if ($this->opportunity_id === null && $opportunity) {\n $this->opportunity_id = $opportunity->id;\n $this->value = $opportunity->value;\n }\n\n $this->save();\n }\n }\n\n public function getActivityProspectData(): array\n {\n return [\n 'lead' => $this->lead_id,\n 'contact' => $this->contact_id,\n 'account' => $this->account_id,\n 'opportunity' => $this->opportunity_id,\n 'stage' => $this->stage_id,\n ];\n }\n\n public function isOrganizer(User $user): bool\n {\n return $this->user_id && $this->user_id === $user->id;\n }\n\n public function isJoinable(): bool\n {\n return \\in_array($this->status, [\n self::STATUS_SCHEDULED,\n self::STATUS_PENDING,\n self::STATUS_RINGING,\n self::STATUS_IN_PROGRESS,\n ], true);\n }\n\n public function isAttemptedForBotJoin(): bool\n {\n return in_array($this->getAttribute('status'), self::MEETING_BOT_JOIN_ATTEMPTED, true);\n }\n\n /**\n * Check if the activity can be saved to CRM (manual or autolog)\n */\n public function isLoggable(): bool\n {\n if ($this->getUser()->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = app(SidekickService::class);\n\n if (! $sidekickService->isSidekickEnabledForUser($this->getUser())) {\n return false;\n }\n }\n\n // If we don't know the activity type, don't try to log.\n if ($this->playbook_category_id === null) {\n return false;\n }\n\n if ($this->user->crm_required === false) {\n return false;\n }\n\n // Don't prompt for internal meetings.\n if ($this->is_internal) {\n return false;\n }\n\n // If we don't know who we are trying to log to, don't try to log.\n if ($this->prospect === null) {\n return false;\n }\n\n $validStatus = false;\n switch ($this->type) {\n case self::TYPE_SOFTPHONE:\n case self::TYPE_SOFTPHONE_INBOUND:\n $validStatus = true;\n\n break;\n case self::TYPE_CONFERENCE:\n $validStatus = in_array($this->status, [\n self::STATUS_BUSY,\n self::STATUS_NO_ANSWER,\n self::STATUS_COMPLETED,\n self::STATUS_CANCELLED,\n ], true);\n\n break;\n case self::TYPE_SMS_INBOUND:\n case self::TYPE_SMS_OUTBOUND:\n $validStatus = in_array($this->status, [\n self::STATUS_QUEUED,\n self::STATUS_SENT,\n self::STATUS_UNDELIVERED,\n self::STATUS_DELIVERED,\n self::STATUS_RECEIVED,\n ], true);\n\n break;\n }\n\n // Depending on the activity channel, we should not try to log.\n return $validStatus;\n }\n\n public function isScheduled(): bool\n {\n return $this->status === self::STATUS_SCHEDULED;\n }\n\n public function scheduledDuration(): int\n {\n if ($this->scheduled_start_time && $this->scheduled_end_time) {\n return $this->scheduled_end_time->timestamp - $this->scheduled_start_time->timestamp;\n }\n\n return 0;\n }\n\n public function isPending(): bool\n {\n return $this->status === self::STATUS_PENDING;\n }\n\n public function isCompleted(): bool\n {\n return $this->status === self::STATUS_COMPLETED;\n }\n\n public function isRinging(): bool\n {\n return $this->status === self::STATUS_RINGING;\n }\n\n public function isInProgress(): bool\n {\n return $this->status === self::STATUS_IN_PROGRESS;\n }\n\n public function isBusy(): bool\n {\n return $this->status === self::STATUS_BUSY;\n }\n\n public function isNoAnswer(): bool\n {\n return $this->status === self::STATUS_NO_ANSWER;\n }\n\n public function isFailed(): bool\n {\n return $this->status === self::STATUS_FAILED;\n }\n\n public function isCancelled(): bool\n {\n return $this->status === self::STATUS_CANCELLED;\n }\n\n public function hasEnded(int $gracePeriodMinutes = 15): bool\n {\n if ($this->isCompleted()) {\n return true;\n }\n\n if (($this->isFailed() || $this->isCancelled()) && $this->hasScheduledEndTime()) {\n return $this->getScheduledEndTime()->addMinutes($gracePeriodMinutes)->isPast();\n }\n\n return false;\n }\n\n public function hasStarted(): bool\n {\n return $this->hasActualStartTime();\n }\n\n public function isOngoing(): bool\n {\n return $this->hasActualStartTime() && ! $this->hasActualEndTime();\n }\n\n public function isTypeSmsInbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_INBOUND;\n }\n\n public function isTypeSmsOutbound(): bool\n {\n return $this->getType() === self::TYPE_SMS_OUTBOUND;\n }\n\n public function isTypeSoftPhone(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE;\n }\n\n public function isTypeSoftphoneInbound(): bool\n {\n return $this->getType() === self::TYPE_SOFTPHONE_INBOUND;\n }\n\n public function isTypeConference(): bool\n {\n return $this->getType() === self::TYPE_CONFERENCE;\n }\n\n /**\n * Get a conference elapsed time in seconds.\n *\n * @return int seconds count\n */\n public function secondsTimeElapsed(): int\n {\n if (empty($this->actual_start_time)) {\n return 0;\n }\n\n // Get number of seconds since conference actual start time\n return (int) abs(Carbon::now()->diffInRealSeconds($this->actual_start_time));\n }\n\n /**\n * Get a conference elapsed time formatted as \"1:30:20\" if more than 1 hour or \"30:20\" otherwise.\n */\n public function formattedTimeElapsed(): string\n {\n // Get number of seconds since conference actual start time.\n $elapsedSeconds = $this->secondsTimeElapsed();\n $elapsedTime = Carbon::createFromTimestampUTC($elapsedSeconds);\n\n // Format conference start time.\n return $elapsedTime->format($elapsedSeconds < 3600 ? 'i:s' : 'G:i:s');\n }\n\n public function wasScheduled(): bool\n {\n return $this->calendarEvent !== null || in_array($this->getSource(), [self::SOURCE_OUTLOOK, self::SOURCE_GOOGLE]);\n }\n\n public function isInstant(): bool\n {\n return ! $this->wasScheduled();\n }\n\n /**\n * GETTERS AND SETTERS FOLLOW BELOW\n */\n\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n public function getFromParticipantId(): ?int\n {\n return $this->getAttribute('from_participant_id');\n }\n\n public function getFromParticipant(): ?Participant\n {\n return $this->getAttribute('from');\n }\n\n public function getToParticipantId(): ?int\n {\n return $this->getAttribute('to_participant_id');\n }\n\n public function getToParticipant(): ?Participant\n {\n return $this->getAttribute('to');\n }\n\n public function hasScheduledStartTime(): bool\n {\n return $this->getAttribute('scheduled_start_time') !== null;\n }\n\n public function getScheduledStartTime(): ?Carbon\n {\n return $this->getAttribute('scheduled_start_time');\n }\n\n public function setScheduledStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_start_time', $dateTime);\n\n return $this;\n }\n\n public function getScheduledEndTime(): ?DateTimeInterface\n {\n return $this->getAttribute('scheduled_end_time');\n }\n\n public function hasScheduledEndTime(): bool\n {\n return $this->getAttribute('scheduled_end_time') !== null;\n }\n\n public function setScheduledEndTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('scheduled_end_time', $dateTime);\n\n return $this;\n }\n\n public function getActualStartTime(): ?Carbon\n {\n return $this->getAttribute('actual_start_time');\n }\n\n public function hasActualStartTime(): bool\n {\n return $this->getAttribute('actual_start_time') !== null;\n }\n\n public function getActualEndTime(): ?Carbon\n {\n return $this->getAttribute('actual_end_time');\n }\n\n public function hasActualEndTime(): bool\n {\n return $this->getAttribute('actual_end_time') !== null;\n }\n\n public function getType(): ?string\n {\n return $this->getAttribute('type');\n }\n\n public function getStatus(): string\n {\n return $this->getAttribute('status');\n }\n\n public function setStatus(string $status): self\n {\n $this->setAttribute('status', $status);\n\n return $this;\n }\n\n public function setActualStartTime(DateTimeInterface $dateTime): self\n {\n $this->setAttribute('actual_start_time', $dateTime);\n\n return $this;\n }\n\n public function setActualEndTime(DateTimeInterface $dateTime, bool $shouldUpdateDuration = true): self\n {\n $this->setAttribute('actual_end_time', $dateTime);\n\n if (! $shouldUpdateDuration) {\n return $this;\n }\n\n return $this->updateDuration();\n }\n\n public function updateDuration(): self\n {\n if (! $this->hasActualStartTime() || ! $this->hasActualEndTime()) {\n return $this;\n }\n\n return $this->setDuration(\n (int) abs($this->getActualStartTime()->diffInRealSeconds($this->getActualEndTime()))\n );\n }\n\n public function setDuration(int $duration): self\n {\n $this->setAttribute('duration', $duration);\n\n return $this;\n }\n\n public function getRecordingState(): string\n {\n return $this->getAttribute('recording_state');\n }\n\n public function isRecordingState(string $recordingState): bool\n {\n return $this->getRecordingState() === $recordingState;\n }\n\n public function setRecordingState(string $recordingState): self\n {\n $this->setAttribute('recording_state', $recordingState);\n\n return $this;\n }\n\n public function hasActivityType(): bool\n {\n return $this->getAttribute('category') !== null;\n }\n\n public function getActivityType(): ?PlaybookCategory\n {\n return $this->getAttribute('category');\n }\n\n public function setActivityType(int $playbookCategoryId): self\n {\n $this->setAttribute('playbook_category_id', $playbookCategoryId);\n\n return $this;\n }\n\n public function hasStage(): bool\n {\n return $this->getAttribute('stage') !== null;\n }\n\n public function getStage(): ?Stage\n {\n return $this->getAttribute('stage');\n }\n\n public function getStageId(): ?int\n {\n return $this->getAttribute('stage_id');\n }\n\n public function setStageId(?int $stageId): void\n {\n $this->setAttribute('stage_id', $stageId);\n }\n\n public function hasOpportunity(): bool\n {\n return $this->getAttribute('opportunity') !== null;\n }\n\n public function getOpportunity(): ?Opportunity\n {\n return $this->getAttribute('opportunity');\n }\n\n public function getOpportunityId(): ?int\n {\n return $this->getAttribute('opportunity_id');\n }\n\n public function setOpportunityId(?int $opportunityId): void\n {\n $this->setAttribute('opportunity_id', $opportunityId);\n }\n\n public function hasContact(): bool\n {\n return $this->getAttribute('contact') !== null;\n }\n\n public function getContact(): ?Contact\n {\n return $this->getAttribute('contact');\n }\n\n public function getContactId(): ?int\n {\n return $this->getAttribute('contact_id');\n }\n\n public function setContactId(?int $contactId): void\n {\n $this->setAttribute('contact_id', $contactId);\n }\n\n public function hasLead(): bool\n {\n return $this->getAttribute('lead') !== null;\n }\n\n public function getLead(): ?Lead\n {\n return $this->getAttribute('lead');\n }\n\n public function getLeadId(): ?int\n {\n return $this->getAttribute('lead_id');\n }\n\n public function setLeadId(?int $leadId): void\n {\n $this->setAttribute('lead_id', $leadId);\n }\n\n public function hasAccount(): bool\n {\n return $this->getAttribute('account') !== null;\n }\n\n public function getAccount(): ?Account\n {\n return $this->getAttribute('account');\n }\n\n public function getAccountId(): ?int\n {\n return $this->getAttribute('account_id');\n }\n\n public function setAccountId(?int $accountId): void\n {\n $this->setAttribute('account_id', $accountId);\n }\n\n /**\n * This method exists to avoid confusion using ->participants() or ->participants. Use the getter instead.\n *\n * @return Collection<int, Participant>|Participant[]\n */\n public function getParticipants(): Collection\n {\n return $this->participants;\n }\n\n /**\n * @deprecated use ParticipantRepository::findParticipantRoomOwner() instead\n */\n public function findParticipantRoomOwner(): ?Participant\n {\n $roomOwnerId = $this->getUserId();\n\n return $this->getParticipants()\n ->filter(static fn (Participant $participant): bool => $participant->isSameUserId($roomOwnerId))\n ->first();\n }\n\n public function hasCrmProviderId(): bool\n {\n return $this->getAttribute('crm_provider_id') !== null;\n }\n\n public function getCrmProviderId(): ?string\n {\n return $this->getAttribute('crm_provider_id');\n }\n\n public function setCrmProviderId(?string $crmProviderId): void\n {\n $this->setAttribute('crm_provider_id', $crmProviderId);\n }\n\n public function getUserId(): ?int\n {\n return $this->getAttribute('user_id');\n }\n\n public function hasUser(): bool\n {\n return $this->user()->exists();\n }\n\n public function getUser(): User\n {\n return $this->getAttribute('user');\n }\n\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n public function isInFiniteState(): bool\n {\n return $this->isFiniteState($this->getStatus());\n }\n\n public function isFiniteState(string $status): bool\n {\n $finiteStates = self::FINITE_STATES[$this->getType()] ?? [];\n\n return in_array($status, $finiteStates, true);\n }\n\n public function getParticipant(Authenticatable $user): Participant\n {\n return $this->findParticipant($user);\n }\n\n public function findParticipant(Authenticatable $user): ?Participant\n {\n if ($user instanceof User) {\n /** @var User $user */\n return $this->participants()->where('user_id', '=', $user->getId())->first();\n }\n\n throw new LogicException(sprintf('Unsupported Authenticatable implementation %s', get_class($user)));\n }\n\n public function hasLanguageCode(): bool\n {\n return $this->getAttribute('language') !== null;\n }\n\n public function getLanguageCode(): ?string\n {\n /** @var string|null */\n return $this->getAttribute('language');\n }\n\n public function getLanguageCodeHyphenated(): string\n {\n return str_replace('_', '-', $this->getLanguageCode() ?? '');\n }\n\n public function getLanguageCodeLocale(): string\n {\n [ $language ] = explode('_', $this->getLanguageCode() ?? '');\n\n return $language;\n }\n\n public function setLanguageCode(string $value): self\n {\n return $this->setAttribute('language', $value);\n }\n\n public function hasSource(): bool\n {\n return $this->getAttribute('source') !== null;\n }\n\n public function setSource(?string $source): self\n {\n return $this->setAttribute('source', $source);\n }\n\n public function isSource(string $source): bool\n {\n return $this->getAttribute('source') === $source;\n }\n\n public function getSource(): ?string\n {\n return $this->getAttribute('source');\n }\n\n public function isSourceGong(): bool\n {\n return $this->isSource(self::SOURCE_GONG);\n }\n\n public function getExternalId(): ?string\n {\n return $this->getAttribute('external_id');\n }\n\n public function setExternalId(?string $externalId): self\n {\n return $this->setAttribute('external_id', $externalId);\n }\n\n public function hasExternalId(): bool\n {\n return $this->getAttribute('external_id') !== null;\n }\n\n public function getProvider(): string\n {\n return $this->getAttribute('provider');\n }\n\n public function hasTelephonyProviderId(): bool\n {\n return $this->getAttribute('telephony_provider_id') !== null;\n }\n\n public function getTelephonyProviderId(): ?string\n {\n return $this->getAttribute('telephony_provider_id');\n }\n\n public function setTelephonyProviderId(?string $telephonyProviderId): self\n {\n return $this->setAttribute('telephony_provider_id', $telephonyProviderId);\n }\n\n public function getLocation(): ?string\n {\n return $this->getAttribute('location');\n }\n\n public function setLocation(?string $location): self\n {\n return $this->setAttribute('location', $location);\n }\n\n public function isDeleted(): bool\n {\n return $this->getAttribute('deleted_at') !== null;\n }\n\n /**\n * Check if activity recording is on and activity status is not one of the failed statuses.\n */\n public function canReviewActivity(): bool\n {\n $failedStatuses = self::$enumFailedStatuses;\n\n return (! in_array($this->recording_state, [self::RECORDING_OFF, self::RECORDING_STOPPED], true) &&\n ! in_array($this->status, $failedStatuses, true));\n }\n\n public function hasReasonCodeBotKicked(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_MEETING_BOT_KICKED);\n }\n\n public function hasReasonCodeNotCompliant(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_CONSENT_DENIED);\n }\n\n public function hasTopicTriggers(): bool\n {\n return $this->topicTriggers()->count() !== 0;\n }\n\n public function getTopicTriggers(): Collection\n {\n return $this->topicTriggers;\n }\n\n public function getTopicTriggersSorted(): Collection\n {\n $this->loadMissing([\n 'topicTriggers.participant',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic',\n 'topicTriggers.playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme',\n ]);\n\n return $this->topicTriggers\n ->sortBy([\n 'playbackThemeTopicTrigger.playbackThemeTopic.playbackTheme.sort',\n 'playbackThemeTopicTrigger.playbackThemeTopic.sort',\n 'playbackThemeTopicTrigger.sort',\n ]);\n }\n\n public function hasQuestions(): bool\n {\n return $this->questions()->exists();\n }\n\n public function getQuestions(): Collection\n {\n return $this->questions;\n }\n\n public function hasValue(): bool\n {\n return $this->getAttribute('value') !== null;\n }\n\n public function getValue(): ?float\n {\n return $this->getAttribute('value');\n }\n\n public function setValue(?float $value): void\n {\n $this->setAttribute('value', $value);\n }\n\n public function transitionTo(string $newState, callable $callback, ?int $timeout = null): self\n {\n $newState = $this->getWorkflowStateFor(\n $this->getType(),\n $newState\n );\n\n return $this->traitTransitionTo($newState, $callback, $timeout);\n }\n\n public function getWorkflowState(): string\n {\n return $this->getWorkflowStateFor(\n $this->getType(),\n $this->getStatus()\n );\n }\n\n public function getActivityProviderDisplayName(): string\n {\n return \\Cache::remember('activity_provider_display_name-' . $this->getProvider(), 60 * 60 * 24, function () {\n $activityProviderRegistry = app()->make(ActivityProviderRegistry::class);\n\n try {\n return $activityProviderRegistry->get($this->getProvider())->getDisplayName();\n } catch (Exception $exception) {\n return ucfirst($this->getProvider());\n }\n });\n }\n\n private function getWorkflowStateFor(string $activityChannel, string $activityStatus): string\n {\n return sprintf(\n '%s::%s',\n $activityChannel,\n $activityStatus\n );\n }\n\n public function getWorkflow(): array\n {\n $map = [\n self::TYPE_SOFTPHONE => [\n self::STATUS_SCHEDULED => [\n self::STATUS_PENDING,\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_PENDING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_RINGING => [\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_IN_PROGRESS,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n self::TYPE_SOFTPHONE_INBOUND => [\n self::STATUS_RINGING => [\n self::STATUS_IN_PROGRESS,\n self::STATUS_NO_ANSWER,\n self::STATUS_CANCELLED,\n self::STATUS_FAILED,\n self::STATUS_BUSY,\n ],\n self::STATUS_IN_PROGRESS => [\n self::STATUS_COMPLETED,\n ],\n ],\n ];\n\n return collect($map)\n ->mapWithKeys(function (array $currentStates, string $activityChannel): array {\n return [\n $activityChannel => collect($currentStates)\n ->mapWithKeys(function (array $possibleStates, $currentState) use ($activityChannel): array {\n $transitionName = $this->getWorkflowStateFor($activityChannel, $currentState);\n\n return [\n $transitionName => array_map(function (string $newState) use ($activityChannel) {\n return $this->getWorkflowStateFor($activityChannel, $newState);\n }, $possibleStates),\n ];\n }),\n ];\n })\n ->reduce(static function (array $carry, Collection $item): array {\n return array_merge($carry, $item->all());\n }, []);\n }\n\n public function hasPosterPath(): bool\n {\n return $this->getAttribute('poster_path') !== null;\n }\n\n public function getPosterPath(): ?string\n {\n return $this->getAttribute('poster_path');\n }\n\n /**\n * Take into account all recording settings and determine if we need to record this activity or not.\n */\n public function shouldRecord(): bool\n {\n return $this->determineRecordingReasonCode() === null;\n }\n\n public function determineRecordingReasonCode(): ?int\n {\n // Conference specific decisions.\n if ($this->isTypeConference()) {\n // If they have manually overridden the recording setting to not record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === false) {\n return self::FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE;\n }\n\n // If they have manually overridden the recording setting to record.\n if ($this->hasRecordingPreference() && $this->getRecordingPreference() === true) {\n return null;\n }\n\n // If their team has disabled recording meetings, don't record.\n if ($this->user->team->isConferenceRecordPreferenceDisabled()) {\n return self::FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED;\n }\n\n // If the host has disabled recording meetings, don't record.\n if ($this->user->checkConferenceRecordPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED;\n }\n\n // If it was marked internal...\n if ($this->is_internal) {\n // and their team has disabled recording internal meetings, don't record.\n if (\n $this->user->team->isConferenceRecordPreferenceEnabled()\n && ! $this->user->team->isConferenceRecordInternalPreferenceEnabled()\n ) {\n return self::FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED;\n }\n\n // and the host has disabled recording internal meetings, don't record.\n if ($this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED;\n }\n }\n\n // If it was not scheduled and they disabled internal meetings, we cannot determine if it was internal.\n if ($this->wasScheduled() === false && $this->user->checkConferenceRecordInternalPreference() === false) {\n return self::FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED;\n }\n }\n\n return null;\n }\n\n public function getRecordingReasonCode(): int\n {\n return $this->getAttribute('recording_reason_code');\n }\n\n public function setRecordingReasonCode(int $recordingReasonCode): self\n {\n $this->setAttribute('recording_reason_code', $recordingReasonCode);\n\n return $this;\n }\n\n // Not used today.\n public function getRecordingReasonString(): ?string\n {\n if ($this->hasRecordingReasonCompliancePrompted()) {\n return Team::COMPLIANCE_MODE_RECORDING_PROMPT;\n }\n\n if ($this->hasRecordingReasonComplianceRestricted()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT;\n }\n\n if ($this->hasRecordingReasonComplianceRestrictedToOneSideRecording()) {\n return Team::COMPLIANCE_MODE_RECORDING_RESTRICT_ONE_SIDE;\n }\n\n return null;\n }\n\n public function hasRecordingReasonComplianceRestricted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT);\n }\n\n public function hasRecordingReasonCompliancePrompted(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_PROMPT);\n }\n\n public function hasRecordingReasonComplianceRestrictedToOneSideRecording(): bool\n {\n return $this->getFlag('recording_reason_code', self::FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE);\n }\n\n public function getAudioTrack(): ?Track\n {\n /** @var Track|null */\n return $this->tracks()\n ->where('type', '=', Track::TYPE_AUDIO)\n ->first();\n }\n\n public function activeParticipants(): HasMany\n {\n return $this->hasMany(Participant::class)->active();\n }\n\n public function getActiveParticipants(): Eloquent\\Collection\n {\n return $this->getAttribute('activeParticipants');\n }\n\n public function crm(): Eloquent\\Relations\\BelongsTo\n {\n return $this->belongsTo(Configuration::class, 'crm_configuration_id');\n }\n\n public function activitySummaryLogs(): HasMany\n {\n return $this->hasMany(ActivitySummaryLog::class);\n }\n\n public function getCrm(): ?Configuration\n {\n return $this->getAttribute('crm');\n }\n\n public function hasCrmConfiguration(): bool\n {\n return $this->getAttribute('crm') !== null;\n }\n\n public function isProcessed(): ?bool\n {\n return $this->getAttribute('is_processed');\n }\n\n public function hasRecordingPrompt(): bool\n {\n return $this->getAttribute('has_recording_prompt') === true;\n }\n\n public function isOnAir(): bool\n {\n return $this->getAttribute('on_air') === self::ON_AIR_READY || $this->getAttribute('on_air') === self::ON_AIR_STREAMING;\n }\n\n public function setOnAir(int $onAir): self\n {\n $this->setAttribute('on_air', $onAir);\n\n return $this;\n }\n\n public function getOnAir(): ?int\n {\n return $this->getAttribute('on_air');\n }\n\n public function setTitleFromCallData(Call $call): void\n {\n $direction = $call->isOutbound() ? 'to' : 'from';\n\n $party = $this->prospect_name\n ?? $call->getContactName()\n ?? $call->getOtherPartyPhoneNumber()\n ;\n\n $this->update(['title' => sprintf('Call %s %s', $direction, $party)]);\n }\n\n /**\n * @param array{}|array{channels:string|null, format:string|null, type:string|null, status:string|null} $audioParams\n */\n public function createAudioTrack(\n string $telephonyProviderId,\n string $recordingUrl,\n array $audioParams = []\n ): Track {\n return $this->tracks()->updateOrCreate([\n 'telephony_provider_id' => $telephonyProviderId,\n ], [\n 'type' => $audioParams['type'] ?? Track::TYPE_AUDIO,\n 'status' => $audioParams['status'] ?? Track::STATUS_PENDING,\n 'format' => $audioParams['format'] ?? Track::FORMAT_WAV,\n 'provider_content_url' => $recordingUrl,\n 'start_time' => $this->actual_start_time,\n 'end_time' => $this->actual_end_time,\n ]);\n }\n\n public function createTrack(string $telephonyProviderId, array $params): Track\n {\n return $this->tracks()->updateOrCreate(\n [\n 'telephony_provider_id' => $telephonyProviderId,\n ],\n $params\n );\n }\n\n public function createOrganiserParticipant(Call $call): Participant\n {\n $user = $this->getUser();\n\n return $this->updateOrCreateParticipant([\n 'is_ghost' => 0,\n 'name' => $user->name,\n 'email' => $user->email,\n 'phone_number' => phone_e164(null, $call->getUserPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'user_id' => $user->id,\n ], false);\n }\n\n public function createProspectParticipant(Call $call): Participant\n {\n // not null 'name' is mandatory here to create a separate participant with 'nameMatching'\n // in case of the same phone_number with the Organiser\n $useNameMatching = $call->getUserPhoneNumber() === $call->getOtherPartyPhoneNumber();\n $defaultName = $useNameMatching ? '' : null;\n\n return $this->updateOrCreateParticipant(data: [\n 'is_ghost' => 0,\n 'name' => $this->prospect->name ?? $defaultName,\n 'email' => $this->prospect->email ?? null,\n 'phone_number' => phone_e164(null, $call->getOtherPartyPhoneNumber()),\n 'enter_time' => $this->actual_start_time,\n 'exit_time' => $this->actual_end_time,\n 'contact_id' => $this->contact_id ?? null,\n 'lead_id' => $this->lead_id ?? null,\n ], enterRoom: false, nameMatching: $useNameMatching);\n }\n\n public function updateParticipants(Participant $organiserParticipant, Participant $prospectParticipant): void\n {\n $this->update([\n 'from_participant_id' => $this->isTypeSoftPhone() ? $organiserParticipant->id : $prospectParticipant->id,\n 'to_participant_id' => $this->isTypeSoftPhone() ? $prospectParticipant->id : $organiserParticipant->id,\n ]);\n }\n\n public function hasProspect(): bool\n {\n return $this->getProspectAttribute() !== null;\n }\n\n public function isPrivate(): bool\n {\n return $this->getAttribute('is_private');\n }\n\n /** Create a new factory instance for the model. */\n protected static function newFactory(): Factory\n {\n return ActivityFactory::new();\n }\n\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n public function getActivitySummaryLogs(): Eloquent\\Collection\n {\n return $this->getAttribute('activitySummaryLogs');\n }\n\n public function hasProspectActivitySummaryLog(): bool\n {\n return $this->getActivitySummaryLogs()->contains(\n 'relation_type',\n ActivitySummaryLog::RELATION_OBJECT_TYPE_PROSPECT\n );\n }\n\n public function getTeam(): Team\n {\n return $this->getUser()->getTeam();\n }\n\n private function getUpdateCrmDataResolver(): UpdateCrmDataResolverInterface\n {\n $factory = app(UpdateCrmDataResolverFactory::class);\n\n return $factory->create($this);\n }\n\n public function getMeetingTrackProviderId(string $type): string\n {\n $label = match ($type) {\n Track::TYPE_VIDEO => 'v',\n Track::TYPE_AUDIO => 'a',\n default => throw new InvalidArgumentJiminnyException('Invalid track type'),\n };\n\n $startTimestamp = $this->getScheduledStartTime()?->getTimestamp();\n $teamId = $this->getTeam()->getId();\n\n return $this->getTelephonyProviderId() . ':' . $label . ':' . $startTimestamp . ':' . $teamId;\n }\n\n /**\n * Get all consent records associated with this activity\n *\n * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n */\n public function participantConsents(): HasMany\n {\n return $this->hasMany(Participant\\Consent::class);\n }\n\n public function isDiallerCall(): bool\n {\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return false;\n }\n\n if (! in_array($this->getType(), [self::TYPE_SOFTPHONE, self::TYPE_SOFTPHONE_INBOUND])) {\n return false;\n }\n\n return $this->getProvider() !== self::PROVIDER_TWILIO;\n }\n\n public function getActivityDateWithFallback(): Carbon\n {\n if ($this->getActualStartTime() !== null) {\n return $this->getActualStartTime();\n }\n\n if ($this->getScheduledStartTime() !== null) {\n return $this->getScheduledStartTime();\n }\n\n return $this->getCreatedAt();\n }\n\n public function getCrmType(): ?string\n {\n // Treat uploader activities as conferences\n if ($this->getProvider() === Activity::PROVIDER_UPLOADER) {\n return Activity::TYPE_CONFERENCE;\n }\n\n return $this->getType();\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"65","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":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01'\n# and id IN (32415, 32416);\nand id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01'\n# and id IN (32415, 32416);\nand id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
8724424516320409755
|
8179532969745786684
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20891-improve-sms-text Project: faVsco.js, menu
JY-20891-improve-sms-text-relays, 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
4
169
4
102
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Carbon\Carbon;
use Database\Factories\ActivityFactory;
use DateTimeInterface;
use Exception;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;
use Jiminny\Component\ElasticSearch;
use Jiminny\Component\MeetingBot;
use Jiminny\Component\Model\BitwiseFlagTrait;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Component\Uuid\UuidAwareInterface;
use Jiminny\Component\Workflow;
use Jiminny\Contracts;
use Jiminny\Contracts\Crm\ProspectInterface;
use Jiminny\DTO\ImportCall\Call;
use Jiminny\Events\Activities\ActivityTypeUpdated;
use Jiminny\Events\Activities\ActivityUpdated;
use Jiminny\Events\Activities\ProspectUpdated;
use Jiminny\Events\Activities\StageUpdated;
use Jiminny\Events\Activities\StatusUpdated;
use Jiminny\Events\Activities\TitleUpdated;
use Jiminny\Exceptions\InvalidArgumentException as InvalidArgumentJiminnyException;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models;
use Jiminny\Models\Activity\ActivitySummaryLog;
use Jiminny\Models\Activity\ActivityUploadSetting;
use Jiminny\Models\Activity\AvailabilityNotification;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Log;
use Jiminny\Models\Activity\Message;
use Jiminny\Models\Activity\Moment;
use Jiminny\Models\Activity\Note;
use Jiminny\Models\Activity\ParticipantSpeech;
use Jiminny\Models\Activity\Play;
use Jiminny\Models\Activity\Question;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\Activity\Snapshot;
use Jiminny\Models\Activity\Stats;
use Jiminny\Models\Activity\SubscriptionSet;
use Jiminny\Models\Activity\TopicTrigger;
use Jiminny\Models\Activity\Transcription;
use Jiminny\Models\Calendar\CalendarEvent;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\ElasticSearch\ActivityElasticSearchTrait;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Participant\Connection;
use Jiminny\Models\Playlist\Activity as PlaylistActivity;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataByStrategy;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverFactory;
use Jiminny\Services\Activity\Import\DataResolvers\UpdateCrmDataResolverInterface;
use Jiminny\Traits\Enums;
use Jiminny\Traits\RequiresUUID;
use Jiminny\Utils\CurrencyFormatter;
use NumberFormatter;
use function in_array;
/**
* Jiminny\Models\Activity
*
* @property null|int $auto_score filled from ES hydrator, not in DB!
* @property-read Account|null $account
* @property-read CalendarEvent|null $calendarEvent
* @property-read Contact|null $contact
* @property-read Lead|null $lead
* @property-read Opportunity|null $opportunity
* @property-read Stage|null $stage
* @property int $id
* @property mixed|null $uuid
* @property string|null $source
* @property string|null $external_id
* @property string $provider
* @property string|null $location
* @property string|null $telephony_provider_id
* @property int|null $from_participant_id
* @property int|null $to_participant_id
* @property int|null $device_id
* @property string|null $type
* @property int|null $playbook_category_id
* @property int $user_id
* @property int|null $lead_id
* @property int|null $account_id
* @property int|null $contact_id
* @property int|null $opportunity_id
* @property int|null $stage_id
* @property string|null $value
* @property int|null $crm_configuration_id
* @property string|null $crm_provider_id
* @property string|null $language
* @property int|null $transcription_id
* @property int $duration
* @property string $status
* @property int|null $on_air
* @property int|null $calendar_event_id
* @property string $recording_state
* @property bool|null $recording_preference
* @property int $recording_reason_code
* @property int $summary_reminder_sent
* @property \Illuminate\Support\Carbon|null $log_reminder_sent_at
* @property \Illuminate\Support\Carbon|null $organizer_notified_at
* @property bool|null $has_recording_prompt
* @property bool $is_internal
* @property int $is_locked
* @property int $is_recording
* @property bool|null $is_processed
* @property bool $is_private
* @property bool $is_instant_invite
* @property string|null $poster_path
* @property string|null $summary
* @property string|null $title
* @property string|null $description
* @property \Illuminate\Support\Carbon|null $scheduled_start_time
* @property \Illuminate\Support\Carbon|null $scheduled_end_time
* @property \Illuminate\Support\Carbon|null $actual_start_time
* @property \Illuminate\Support\Carbon|null $actual_end_time
* @property int|null $uploaded_by
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $average_score
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $activeParticipants
* @property-read int|null $active_participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRuleTrigger> $activityScorecardRuleTriggers
* @property-read int|null $activity_scorecard_rule_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Scorecard\ActivityScorecardRule> $activityScorecardRules
* @property-read int|null $activity_scorecard_rules_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, AvailabilityNotification> $availabilityNotifications
* @property-read int|null $availability_notifications_count
* @property-read \Jiminny\Models\PlaybookCategory|null $category
* @property-read \Illuminate\Database\Eloquent\Collection<int, CoachRequest> $coachRequests
* @property-read int|null $coach_requests_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $coachingFeedbacks
* @property-read int|null $coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $coachingMessages
* @property-read int|null $coaching_messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $comments
* @property-read int|null $comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Connection> $connections
* @property-read int|null $connections_count
* @property-read Configuration|null $crm
* @property-read \Illuminate\Database\Eloquent\Collection<int, FieldData> $data
* @property-read int|null $data_count
* @property-read \Jiminny\Models\Device|null $device
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $favoritePlaylists
* @property-read int|null $favorite_playlists_count
* @property-read \Jiminny\Models\Participant|null $from
* @property-read string|null $activity_title
* @property-read mixed $comment_count
* @property-read mixed $duration_for_humans
* @property-read string $duration_for_humans_short
* @property-read int $favorite_count
* @property-read mixed $favorites_count
* @property-read mixed $formatted_value
* @property-read string $id_string
* @property-read \Jiminny\Models\Participant|null $organizer
* @property-read mixed $play_count
* @property-read int|null $plays_count
* @property-read ?ProspectInterface $prospect
* @property-read string|null $prospect_name
* @property-read mixed $prospect_type
* @property-read mixed $share_count
* @property-read int|null $shares_count
* @property-read int|null $tracks_with_telephony_count
* @property-read int|null $visible_comments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\CoachingFeedback> $latestCoachingFeedbacks
* @property-read int|null $latest_coaching_feedbacks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Log> $logs
* @property-read int|null $logs_count
* @property-read \Jiminny\Models\Track|null $masterTrack
* @property-read \Illuminate\Database\Eloquent\Collection<int, Message> $messages
* @property-read int|null $messages_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Moment> $moments
* @property-read int|null $moments_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Note> $notes
* @property-read int|null $notes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\Share> $participantShares
* @property-read int|null $participant_shares_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, ParticipantSpeech> $participantSpeeches
* @property-read int|null $participant_speeches_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant\ParticipantStats> $participantStats
* @property-read int|null $participant_stats_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Participant> $participants
* @property-read int|null $participants_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, PlaylistActivity> $playlistActivities
* @property-read int|null $playlist_activities_count
* @property-read \Kalnoy\Nestedset\Collection<int, \Jiminny\Models\Playlist> $playlists
* @property-read int|null $playlists_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Play> $plays
* @property-read \Illuminate\Database\Eloquent\Collection<int, Question> $questions
* @property-read int|null $questions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Session> $sessions
* @property-read int|null $sessions_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, Share> $shares
* @property-read \Illuminate\Database\Eloquent\Collection<int, Snapshot> $snapshots
* @property-read int|null $snapshots_count
* @property-read Stats|null $stats
* @property-read \Jiminny\Models\Participant|null $to
* @property-read \Illuminate\Database\Eloquent\Collection<int, TopicTrigger> $topicTriggers
* @property-read int|null $topic_triggers_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracks
* @property-read int|null $tracks_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Jiminny\Models\Track> $tracksWithTelephony
* @property-read Transcription|null $transcription
* @property-read \Jiminny\Models\User $user
* @property-read \Illuminate\Database\Eloquent\Collection<int, Comment> $visibleComments
*
* @method static \Illuminate\Database\Eloquent\Collection<int, static> all($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity chunkByIdDesc($count, callable $callback, $column = null, $alias = null)
* @method static \Database\Factories\ActivityFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Collection<int, static> get($columns = ['*'])
* @method static \Jiminny\Component\Eloquent\Builder|Activity heldBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity idOrUuId($idOrUuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity newModelQuery()
* @method static \Jiminny\Component\Eloquent\Builder|Activity newQuery()
* @method static Builder|Activity onlyTrashed()
* @method static \Jiminny\Component\Eloquent\Builder|Activity query()
* @method static \Jiminny\Component\Eloquent\Builder|Activity scheduledBetween(\Carbon\Carbon $start, \Carbon\Carbon $end)
* @method static \Jiminny\Component\Eloquent\Builder|Activity inOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity notInOpenDeals()
* @method static \Jiminny\Component\Eloquent\Builder|Activity forTeam(int $teamId)
* @method static \Jiminny\Component\Eloquent\Builder|Activity search(callable $searchQuery, $key = null, $sortByResults = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity uuid(string $uuid, bool $first = true)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAccountId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereActualStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereAverageScore($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCalendarEventId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereContactId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCreatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmConfigurationId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereCrmProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeletedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDescription($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDeviceId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereDuration($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereFromParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereHasRecordingPrompt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInstantInvite($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsInternal($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsLocked($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsPrivate($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsProcessed($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereIsRecording($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLanguage($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLeadId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLocation($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereLogReminderSentAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOnAir($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOpportunityId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereOrganizerNotifiedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePlaybookCategoryId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity wherePosterPath($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereProvider($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingPreference($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingReasonCode($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereRecordingState($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledEndTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereScheduledStartTime($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSource($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereExternalId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStageId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereStatus($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummary($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereSummaryReminderSent($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTelephonyProviderId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTitle($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereToParticipantId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereTranscriptionId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereType($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUpdatedAt($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUploadedBy($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUserId($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereUuid($value)
* @method static \Jiminny\Component\Eloquent\Builder|Activity whereValue($value)
* @method static Builder|Activity withTrashed()
* @method static Builder|Activity withoutTrashed()
*
* @mixin \Eloquent
*/
class Activity extends Model implements
ElasticSearch\Contract\Searchable,
Workflow\Workflow\WorkflowAwareInterface,
Models\Contracts\ActivityContract,
Contracts\Model\ActivityInterface,
UuidAwareInterface
{
use HasFactory;
use Enums;
use SoftDeletes;
use RequiresUUID;
use BitwiseFlagTrait;
use ElasticSearch\Model\Searchable;
use ActivityElasticSearchTrait;
use Workflow\Workflow\WorkflowAware {
transitionTo as traitTransitionTo;
}
public const int FLAG_RECORDING_REASON_DEFAULT = 0;
// Recording Prompted but never started
public const int FLAG_RECORDING_REASON_COMPLIANCE_PROMPT = 1;
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESUMED = 2;
public const int FLAG_RECORDING_REASON_NO_AUDIO = 3;
// Recording Disabled by Organization
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT = 4;
// Recording was restricted to one-side recordings only
public const int FLAG_RECORDING_REASON_COMPLIANCE_RESTRICT_ONE_SIDE = 8;
// Recording was not started because it was internal and team setting disabled that.
public const int FLAG_RECORDING_REASON_TEAM_INTERNAL_DISABLED = 16;
// Recording was not started because it was internal and user setting disabled that.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED = 32;
// Recording was not started because user setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_USER_AUTOMATIC_DISABLED = 64;
// Recording was not started because team setting disabled automatic recording.
public const int FLAG_RECORDING_REASON_TEAM_AUTOMATIC_DISABLED = 128;
// Recording was not started because user has overriden default.
public const int FLAG_RECORDING_REASON_PREFERENCE_OVERRIDE = 256;
// Recording was not started because they don't want internal, and this meeting was not scheduled/imported in time.
public const int FLAG_RECORDING_REASON_USER_INTERNAL_DISABLED_UNSCHEDULED = 512;
// Recording was not started because their team setting does excludes the meeting type.
public const int FLAG_RECORDING_REASON_UNSUPPORTED_TYPE = 1024;
// Recording was not started because the external provider disabled it (or recording is missing etc).
public const int FLAG_RECORDING_REASON_EXTERNALLY_DISABLED = 2048;
// Recording was stopped externally ("exit-meeting" Pusher event)
public const int FLAG_RECORDING_REASON_STOPPED_EXTERNALLY = 384;
// Recording couldn't be started due to Zoom hosting conflict error
public const int FLAG_RECORDING_REASON_HOSTING_CONFLICT = 448;
// meeting.failed event with reason code BOT_DENIED_FROM_LOBBY
public const int FLAG_RECORDING_REASON_MEETING_BOT_DENIED_FROM_LOBBY = 4096;
// meeting.failed event with reason code LOBBY_TIMEOUT
public const int FLAG_RECORDING_REASON_MEETING_BOT_LOBBY_TIMEOUT = 8192;
// meeting.failed event with reason code BOT_KICKED
public const int FLAG_RECORDING_REASON_MEETING_BOT_KICKED = 16384;
// meeting.failed event with reason code UNKNOWN
public const int FLAG_RECORDING_REASON_MEETING_BOT_UNKNOWN = 32768;
public const int FLAG_RECORDING_REASON_CONSENT_DENIED = 65536;
// Invalid meeting (e.g. URL is invalid, or the meeting is not found)
public const int FLAG_RECORDING_REASON_MEETING_BOT_INVALID = 131072;
// The host stopped the recording.
public const int FLAG_RECORDING_REASON_USER_STOPPED = 262144;
// Recording was not started because an alternative vendor disabled it (or overrode it).
public const int FLAG_RECORDING_REASON_VENDOR_OVERRIDE = 1048576;
// Login required meeting.failed code
public const int FLAG_RECORDING_REASON_LOGIN_REQUIRED = 524288;
// Password for meeting was not provided - meeting.failed code
public const int FLAG_RECORDING_REASON_MEETING_PASSWORD_NOT_PROVIDED = 2097152;
// meeting.failed - when the meeting is locked
public const int FLAG_RECORDING_REASON_MEETING_IS_LOCKED = 4194304;
// max recording duration reached
public const int FLAG_RECORDING_REASON_MAX_DURATION_REACHED = 8388608;
// recording size is too small
public const int FLAG_RECORDING_REASON_EMPTY_RECORDING = 16777216;
// meeting.failed - when bot is redirected to sign in page multiple times
public const int FLAG_RECORDING_REASON_MAX_RESTART_COUNT_IS_REACHED = 33554432;
// meeting.failed event with reason code CONNECTION_LOST
public const int FLAG_RECORDING_REASON_MEETING_BOT_CONNECTION_LOST = 67108864;
// recording is corrupted.
public const int FLAG_RECORDING_REASON_MEDIA_FILE_UNSUPPORTED_MIME_TYPE = 134217728;
// meeting ended in lobby
public const int FLAG_RECORDING_REASON_MEETING_ENDED_IN_LOBBY = 268435456;
// meeting not started
public const int FLAG_RECORDING_REASON_REASON_MEETING_NOT_STARTED = 536870912;
// unfinished zoom custom disclaimer
public const int FLAG_RECORDING_REASON_FEATURE_RULE_NOT_FOUND_ERROR = 1073741824;
// recording download failed - server error
public const int FLAG_RECORDING_REASON_SERVER_ERROR = 2147483648;
// recording download failed - client code 404
public const int FLAG_RECORDING_REASON_NOT_FOUND = 2147483649;
// recording download failed - client code 401, 403
public const int FLAG_RECORDING_REASON_ACCESS_DENIED = 2147483650;
// recording download failed - client code 429
public const int FLAG_RECORDING_REASON_TOO_MANY_REQUESTS = 2147483651;
// recording download failed - unknown client error
public const int FLAG_RECORDING_REASON_CLIENT_ERROR = 2147483652;
// recording download failed - unknown error
public const int FLAG_RECORDING_REASON_UNKNOWN_ERROR = 2147483653;
// It has been setup ahead of time through calendar
public const string STATUS_SCHEDULED = 'scheduled';
// It is awaiting audio.
public const string STATUS_PENDING = 'pending';
// Participant(s) dialed in, awaiting organizer.
public const string STATUS_RINGING = 'ringing';
// Call is in progress.
public const string STATUS_IN_PROGRESS = 'in-progress';
// It has ended.
public const string STATUS_COMPLETED = 'completed';
// Cancelled prior to starting.
public const string STATUS_CANCELLED = 'canceled';
public const string STATUS_DUPLICATED = 'duplicated'; // duplicated conference
public const string STATUS_STARTING_SOON = 'starting-soon';
public const string STATUS_BOT_CREATE_SENT = 'bot-create-sent';
public const string STATUS_BOT_INSTANCE_WORKER_ASSIGNED = 'worker-assigned';
public const string STATUS_BOT_INSTANCE_STARTED = 'bot-started';
// When bot instance is waiting in lobby
public const string STATUS_BOT_INSTANCE_WAITING_LOBBY = 'bot-waiting';
public const string STATUS_BUSY = 'busy';
public const string STATUS_NO_ANSWER = 'no-answer';
public const string STATUS_FAILED = 'failed'; // Used by SMS too
// SMS related
public const string STATUS_ACCEPTED = 'accepted';
public const string STATUS_QUEUED = 'queued';
public const string STATUS_SENDING = 'sending';
public const string STATUS_SENT = 'sent';
public const string STATUS_DELIVERED = 'delivered';
public const string STATUS_UNDELIVERED = 'undelivered';
public const string STATUS_RECEIVING = 'receiving';
public const string STATUS_RECEIVED = 'received';
public const string STATUS_RESENT = 'resent';
public const array SMS_STATUSES = [
Activity::STATUS_RECEIVED,
Activity::STATUS_SENT,
Activity::STATUS_DELIVERED,
];
public const array SOFT_PHONE_CONFERENCE_STATUSES = [
Activity::STATUS_IN_PROGRESS,
Activity::STATUS_COMPLETED,
];
// @todo refactor prefix from `TYPE_` to `CHANNEL_`
public const string TYPE_SOFTPHONE = 'softphone';
public const string TYPE_SOFTPHONE_INBOUND = 'softphone-inbound';
public const string TYPE_CONFERENCE = 'conference';
public const string TYPE_SMS_INBOUND = 'sms-inbound';
public const string TYPE_SMS_OUTBOUND = 'sms-outbound';
public const string TYPE_EMAIL_INBOUND = 'email-inbound';
public const string TYPE_EMAIL_OUTBOUND = 'email-outbound';
public const array CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
public const array PLAYABLE_CHANNELS = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
];
// Recording States
public const string RECORDING_OFF = 'off'; // Default state
public const string RECORDING_IN_PROGRESS = 'in-progress';
public const string RECORDING_PAUSED = 'paused';
public const string RECORDING_STOPPED = 'stopped'; // To never be resumed.
public const string RECORDING_RECORDED = 'recorded'; // At least some portion of it was recorded.
public const string RECORDING_FAILED = 'failed'; // Recording was attempted but failed for some reason.
// Live Stream States
public const int ON_AIR_DEFAULT = 0;
public const int ON_AIR_READY = 1;
public const int ON_AIR_PREPARING = 2;
public const int ON_AIR_STREAMING = 3;
public const int ON_AIR_FINISHED = 4;
public const int ON_AIR_NOT_STREAMED = 5;
public const int ON_AIR_ERROR = -1;
public const string SOURCE_GONG = 'gong';
public const string SOURCE_CHORUS = 'chorus';
public const string SOURCE_OUTLOOK = 'outlook';
public const string SOURCE_GOOGLE = 'google';
// Activity Providers
public const string PROVIDER_TWILIO = 'twilio'; // XXX: This is run via the Jiminny Provider.
public const string PROVIDER_OUTREACH = 'outreach';
public const string PROVIDER_ZOOM_BOT = 'zoom-bot';
public const string PROVIDER_SALESLOFT = 'salesloft';
public const string PROVIDER_GOOGLE = 'google';
public const string PROVIDER_AIRCALL = 'aircall';
public const string PROVIDER_JUSTCALL = 'justcall';
public const string PROVIDER_GOOGLE_MEET = 'google-meet';
public const string PROVIDER_GONG = 'gong';
public const string PROVIDER_HUBSPOT = 'hubspot';
public const string PROVIDER_CLOSE = 'close';
public const string PROVIDER_TEAMS = 'ms-teams';
public const string PROVIDER_SALESFORCE = 'salesforce';
public const string PROVIDER_GROOVE = 'groove';
public const string PROVIDER_XANT = 'xant';
public const string PROVIDER_OFFICE = 'office';
public const string PROVIDER_NATTERBOX = 'natterbox';
public const string PROVIDER_RINGCENTRAL = 'ringcentral';
public const string PROVIDER_RINGCENTRAL_VIDEO = 'ringcentral-video';
public const string PROVIDER_GOTOMEETING = 'go-to-meeting';
public const string PROVIDER_DEMODESK = 'demo-desk';
public const string PROVIDER_DIALPAD = 'dialpad';
public const string PROVIDER_ZOOM_PHONE = 'zoom-phone';
public const string PROVIDER_CLOUDCALL = 'cloudcall';
public const string PROVIDER_CLOUDCALL_US = 'cloudcall-us';
public const string PROVIDER_EIGHT_BY_EIGHT = 'eight-by-eight'; // "8x8" UK
public const string PROVIDER_EIGHT_BY_EIGHT_CA = 'eight-by-eight-ca'; // "8x8" Canada
public const string PROVIDER_EIGHT_BY_EIGHT_AP = 'eight-by-eight-ap'; // "8x8" Australia
public const string PROVIDER_EIGHT_BY_EIGHT_US_EAST = 'eight-by-eight-use'; // "8x8" US East
public const string PROVIDER_EIGHT_BY_EIGHT_US_WEST = 'eight-by-eight-usw'; // "8x8" US West
public const string PROVIDER_CONNECT_AND_SELL = 'connect-and-sell';
public const string PROVIDER_CLOUD_TALK = 'cloud-talk';
public const string PROVIDER_AMAZON_CONNECT = 'amazon-connect';
public const string PROVIDER_VONAGE = 'vonage';
public const string PROVIDER_MIGRATOR = 'migrator';
public const string PROVIDER_UPLOADER = 'uploader';
public const string PROVIDER_TALKDESK = 'talkdesk';
public const string PROVIDER_TWILIO_FLEX = 'twilio-flex';
public const string PROVIDER_TWILIO_FLEX_DIRECT = 'twilio-flex-direct';
public const string PROVIDER_TWILIO_VIDEO = 'twilio-video';
public const string PROVIDER_AVAYA = 'avaya';
public const string PROVIDER_TELUS = 'telus';
public const string PROVIDER_FIVE_NINE = 'five-nine';
public const string PROVIDER_APOLLO = 'apollo';
public const string PROVIDER_ORUM = 'orum';
public const string PROVIDER_BLOOBIRDS = 'bloobirds';
/**
* @const API_PROVIDERS
* A list of integrations that import calls via API instead of webhooks
*/
public const array API_PROVIDERS = [
self::PROVIDER_OUTREACH,
self::PROVIDER_SALESLOFT,
self::PROVIDER_HUBSPOT,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_NATTERBOX,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
];
public const array FINITE_STATES = [
self::TYPE_SOFTPHONE => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_SOFTPHONE_INBOUND => [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_NO_ANSWER,
self::STATUS_BUSY,
],
self::TYPE_CONFERENCE => self::FINITE_STATES_CONFERENCE,
];
public const array FINITE_STATES_CONFERENCE = [
self::STATUS_COMPLETED,
self::STATUS_FAILED,
self::STATUS_CANCELLED,
];
public const array MEETING_BOT_JOIN_ATTEMPTED = [
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_BOT_INSTANCE_STARTED,
];
public static array $enumStatuses = [
self::STATUS_SCHEDULED,
self::STATUS_PENDING,
self::STATUS_RINGING,
self::STATUS_IN_PROGRESS,
self::STATUS_COMPLETED,
self::STATUS_CANCELLED,
self::STATUS_BUSY,
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_ACCEPTED,
self::STATUS_QUEUED,
self::STATUS_SENDING,
self::STATUS_SENT,
self::STATUS_RESENT,
self::STATUS_DELIVERED,
self::STATUS_UNDELIVERED,
self::STATUS_RECEIVING,
self::STATUS_RECEIVED,
self::STATUS_BOT_INSTANCE_WAITING_LOBBY,
self::STATUS_STARTING_SOON,
self::STATUS_BOT_INSTANCE_WORKER_ASSIGNED,
self::STATUS_BOT_INSTANCE_STARTED,
self::STATUS_DUPLICATED,
];
public static array $enumProviders = [
self::PROVIDER_TWILIO,
self::PROVIDER_OUTREACH,
self::PROVIDER_ZOOM_BOT,
self::PROVIDER_SALESLOFT,
self::PROVIDER_AIRCALL,
self::PROVIDER_JUSTCALL,
self::PROVIDER_GOOGLE_MEET,
self::PROVIDER_GONG,
self::PROVIDER_HUBSPOT,
self::PROVIDER_CLOSE,
self::PROVIDER_TEAMS,
self::PROVIDER_SALESFORCE,
self::PROVIDER_GROOVE,
self::PROVIDER_XANT,
self::PROVIDER_GOOGLE,
self::PROVIDER_OFFICE,
self::PROVIDER_NATTERBOX,
self::PROVIDER_RINGCENTRAL,
self::PROVIDER_RINGCENTRAL_VIDEO,
self::PROVIDER_GOTOMEETING,
self::PROVIDER_DEMODESK,
self::PROVIDER_DIALPAD,
self::PROVIDER_ZOOM_PHONE,
self::PROVIDER_CLOUDCALL,
self::PROVIDER_CLOUDCALL_US,
self::PROVIDER_EIGHT_BY_EIGHT,
self::PROVIDER_EIGHT_BY_EIGHT_CA,
self::PROVIDER_EIGHT_BY_EIGHT_AP,
self::PROVIDER_EIGHT_BY_EIGHT_US_EAST,
self::PROVIDER_EIGHT_BY_EIGHT_US_WEST,
self::PROVIDER_CONNECT_AND_SELL,
self::PROVIDER_CLOUD_TALK,
self::PROVIDER_AMAZON_CONNECT,
self::PROVIDER_VONAGE,
self::PROVIDER_TALKDESK,
self::PROVIDER_TWILIO_FLEX,
self::PROVIDER_TWILIO_FLEX_DIRECT,
self::PROVIDER_TWILIO_VIDEO,
self::PROVIDER_AVAYA,
self::PROVIDER_TELUS,
self::PROVIDER_FIVE_NINE,
self::PROVIDER_APOLLO,
self::PROVIDER_ORUM,
self::PROVIDER_BLOOBIRDS,
];
public static $enumRecordingStates = [
self::RECORDING_OFF, // Default state
self::RECORDING_IN_PROGRESS,
self::RECORDING_PAUSED,
self::RECORDING_STOPPED,
self::RECORDING_RECORDED,
self::RECORDING_FAILED,
];
// @Important:
// This collection is not used anywhere, and is fully duplicated by the Channels const.
// Validate if it is referred somehow via the enum trait, and if not, remove it entirely.
// An even better strategy will be to move all those constants to a dedicated class
protected array $enumTypes = [
self::TYPE_SOFTPHONE,
self::TYPE_SOFTPHONE_INBOUND,
self::TYPE_CONFERENCE,
self::TYPE_SMS_INBOUND,
self::TYPE_SMS_OUTBOUND,
self::TYPE_EMAIL_INBOUND,
self::TYPE_EMAIL_OUTBOUND,
];
protected static $enumFailedStatuses = [
self::STATUS_NO_ANSWER,
self::STATUS_FAILED,
self::STATUS_BUSY,
self::STATUS_CANCELLED,
];
protected $table = 'activities';
protected $fillable = [
// Type of activity.
'type', // @todo refactor to `channel`
// The activity type.
'playbook_category_id',
// User who hosts the activity.
'user_id',
// Related Lead record (if applicable)
'lead_id',
// Related Account record (if applicable)
'account_id',
// Related Contact record (if applicable)
'contact_id',
// Related Opportunity record (if applicable)
'opportunity_id',
// Stage of activity.
'stage_id',
// Value of opportunity.
'value',
// If the activity relates to a CRM task.
'crm_provider_id',
// If the activity was created through an external device.
'device_id',
// the activity's language code
'language',
// transcription id
'transcription_id',
// Duration of the call, with microseconds precision.
'duration',
// One of enumStatuses above.
'status',
// Have we reminded them to log the call?
'log_reminder_sent_at',
// If activity is private or inter-org, flagged here.
'is_internal',
// Managers and above can mark a call as private, to exclude it from other team members
'is_private',
'is_processed',
// Boolean for this activity being instant invite handled.
'is_instant_invite',
// If activity is in recording state, flagged here.
'recording_state',
// If activity recording is overidden from default.
'recording_preference',
// if recording did (not) happen, why that is
'recording_reason_code',
// Average score, updated during
'average_score',
// Summary that the organizer has taken after the call.
'summary',
// Subject of the activity, usually taken from calendar event.
'title',
// Description of the activity, usually taken from calendar event.
'description',
// Start time, usually taken from calendar event.
'scheduled_start_time',
// End time, usually taken from calendar event.
'scheduled_end_time',
// When the call actually started.
'actual_start_time',
// When the call actually ended.
'actual_end_time',
// SMS: Message reference
'telephony_provider_id',
// SMS: Participant who sent message
'from_participant_id',
// SMS: Participant who should receive the message
'to_participant_id',
// When an external guest joins an organizers meeting room and the organizer is not present,
// send them an SMS notification that someone has joined.
'organizer_notified_at',
// where was the activity imported from
'source',
// The id in the source system (e.g. the bot id in Recall.ai)
'external_id',
// The provider, by default it is twilio.
'provider',
// Meeting location url
'location',
// The snapshot for displaying a poster image.
'poster_path',
'crm_configuration_id',
// If there is an automated message that the conversation is being recorded
'has_recording_prompt',
// If the activity is being live-streamed
'on_air',
'calendar_event_id',
];
protected $appends = [
'id_string',
'organizer',
];
protected $hidden = [
'uuid',
];
protected $visible = [
'id_string',
'type',
'duration',
'average_score',
'status',
'log_reminder_sent_at',
'title',
'description',
'is_internal',
'scheduled_start_time',
'scheduled_end_time',
'actual_start_time',
'actual_end_time',
'user',
'category',
'account',
'contact',
'opportunity',
'lead',
'stage',
'stats',
'participants',
'playlists',
'tracks',
'comments',
'plays',
'coachingFeedbacks',
'shares',
'favorites',
'language',
'transcription',
'is_private',
'is_instant_invite',
'on_air',
'calendar_event_id',
];
protected function casts(): array
{
return [
'scheduled_start_time' => 'datetime',
'scheduled_end_time' => 'datetime',
'actual_start_time' => 'datetime',
'actual_end_time' => 'datetime',
'organizer_notified_at' => 'datetime',
'log_reminder_sent_at' => 'datetime',
'is_internal' => 'boolean',
'duration' => 'integer',
'average_score' => 'decimal:2',
'is_private' => 'boolean',
'is_processed' => 'boolean',
'is_instant_invite' => 'boolean',
'value' => 'decimal:2',
'recording_preference' => 'boolean',
'recording_reason_code' => 'integer',
'has_recording_prompt' => 'boolean',
'on_air' => 'integer',
];
}
protected static function boot()
{
parent::boot();
static::updated(static function (Activity $activity) {
// If activity is about to start (pending, ringing, in-progress) or event is scheduled in less than 1 week
if (in_array($activity->status, [Activity::STATUS_PENDING, Activity::STATUS_RINGING, Activity::STATUS_IN_PROGRESS], true) ||
($activity->scheduled_start_time && (int) $activity->scheduled_start_time->diffInWeeks(new Carbon(), true) < 1)) {
if ($activity->isDirty('status')) {
event(new StatusUpdated($activity));
}
if ($activity->isDirty('stage_id')) {
event(new StageUpdated($activity));
}
if ($activity->isDirty(['lead_id', 'account_id', 'contact_id'])) {
event(new ProspectUpdated($activity));
}
if ($activity->isDirty('opportunity_id')) {
event(new ActivityUpdated($activity, 'activity.opportunity-updated', Auth::user()));
}
if ($activity->isDirty('title')) {
event(new TitleUpdated($activity));
}
}
if ($activity->isDirty('playbook_category_id')) {
event(new ActivityTypeUpdated($activity));
}
});
static::deleted(static function (Activity $activity) {
// Hard delete associated playlistActivities
$activity->playlistActivities()->delete();
});
}
public function getOrganizerAttribute(): ?Participant
{
$participant = $this->participants()->where('user_id', $this->user_id)->first();
if (! $participant instanceof Participant && $participant !== null) {
throw new RuntimeException(sprintf('$participant must be an instance of "%s" or null', Participant::class));
}
return $participant;
}
public function getFormattedValueAttribute()
{
$currencyCode = 'USD';
if ($this->opportunity) {
$currencyCode = $this->opportunity->getCurrencyCode();
}
$formatter = new CurrencyFormatter();
$formatter->setTextAttribute(NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 0);
return $formatter->format($this->value, $currencyCode);
}
public function getProspectNameAttribute(): ?string
{
$prospectName = null;
if ($this->lead_id) {
$prospectName = $this->lead->name;
} elseif ($this->contact_id) {
$prospectName = $this->contact->name;
} elseif ($this->account_id) {
$prospectName = $this->account->name;
}
return $prospectName;
}
public function getProspectName(): ?string
{
/** @var string|null */
return $this->getAttribute('prospect_name');
}
/**
* Get activity title depending on prospect or title
*/
public function getActivityTitleAttribute(): ?string
{
$activityTitle = null;
if ($this->prospect && $this->prospect->getName()) {
if ($this->account_id) {
$activityTitle = $this->account->name;
} elseif ($this->lead_id) {
$activityTitle = $this->lead->company;
} elseif ($this->contact_id) {
$activityTitle = $this->contact->account ? $this->contact->account->name : $this->contact->name;
}
} elseif ($this->title) {
$activityTitle = $this->title;
}
return $activityTitle;
}
public function wasRecentlyCreated(): bool
{
return $this->wasRecentlyCreated;
}
public function getProspectTypeAttribute()
{
$prospectType = null;
if ($this->lead_id) {
$prospectType = 'Lead';
} elseif ($this->contact_id) {
$prospectType = 'Contact';
} elseif ($this->account_id) {
$prospectType = 'Account';
}
return $prospectType;
}
/**
* Return the best match for prospect. Results are in the following order of priority:
* 1. Lead
* 2. Contact
* 3. Account
* 4. NULL
*/
public function getProspectAttribute(): ?ProspectInterface
{
if ($this->hasLead()) {
return $this->getLead();
}
if ($this->hasContact()) {
return $this->getContact();
}
if ($this->hasAccount()) {
return $this->getAccount();
}
return null;
}
public function getTitleAttribute($value): ?string
{
return \getActivityTitleAttribute(
$this->user->name,
$this->getType(),
$value,
$this->prospect->name ?? null,
$this->from->national_phone_number ?? null
);
}
public function getTitle(): ?string
{
return $this->getAttribute('title');
}
public function getSummary(): ?string
{
return $this->getAttribute('summary');
}
public function isInternal(): bool
{
return $this->getAttribute('is_internal');
}
public function getIsPrivate(): bool
{
return $this->getAttribute('is_private');
}
public function getDescription(): ?string
{
return $this->getAttribute('description');
}
public function hasTitle(): bool
{
return $this->getOriginal('title') !== null;
}
public function getPlayCountAttribute()
{
return $this->getPlaysCountAttribute();
}
public function getPlaysCountAttribute()
{
if (! isset($this->attributes['plays_count'])) {
$this->loadCount('plays');
}
return $this->attributes['plays_count'];
}
public function getCommentCountAttribute()
{
return $this->getCommentsCountAttribute();
}
public function getCommentsCountAttribute()
{
if (! isset($this->attributes['comments_count'])) {
$this->loadCount('comments');
}
return $this->attributes['comments_count'];
}
public function getVisibleCommentsCountAttribute()
{
if (! isset($this->attributes['visible_comments_count'])) {
$activityCommentsService = app(ActivityCommentService::class);
$user = Auth::user() instanceof User ? Auth::user() : null;
$this->attributes['visible_comments_count'] = $activityCommentsService
->getVisibleCommentsCount($this, $user);
}
return $this->attributes['visible_comments_count'];
}
public function getShareCountAttribute()
{
return $this->getSharesCountAttribute();
}
public function getSharesCountAttribute()
{
if (! isset($this->attributes['shares_count'])) {
$this->loadCount('shares');
}
return $this->attributes['shares_count'];
}
/**
* Get the count of favorites playlists this activity appears in
*/
public function getFavoriteCountAttribute(): int
{
return $this->getFavoritesCountAttribute();
}
public function getFavoritesCountAttribute()
{
if (! isset($this->attributes['favorites_count'])) {
$this->loadCount('favorites');
}
return $this->attributes['favorites_count'];
}
public function getActiveParticipantsCountAttribute()
{
if (! isset($this->attributes['active_participants_count'])) {
$this->loadCount('activeParticipants');
}
return $this->attributes['active_participants_count'];
}
public function getTracksWithTelephonyCountAttribute()
{
if (! isset($this->attributes['tracks_with_telephony_count'])) {
$this->loadCount('tracksWithTelephony');
}
return $this->attributes['tracks_with_telephony_count'];
}
/**
* @TEMP
* $this->loadCount('tracksWithTelephony') throws null pointer exception
*/
public function countTracksWithTelephony(): int
{
return $this->tracks()->whereNotNull('telephony_provider_id')->count();
}
public function getDuration(): float
{
return $this->getAttribute('duration');
}
public function getDurationForHumansAttribute()
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true);
}
public function getDurationForHumansShortAttribute(): string
{
return Carbon::now()->subSeconds($this->duration)->diffForHumans(now(), true, true);
}
public...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47831
|
1698
|
36
|
2026-05-15T08:56:09.531982+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835369531_m1.jpg...
|
PhpStorm
|
faVsco.js – Activity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpllolJiminny Tech Day • 6h 4 m leftA100% [8•Fri 15 May 11:56:09DOCKERO ₴1DEV (-zsh)82whisper_init_state:computebuffer(encode)whisper_init_state:compute buffer(cross)=whisper_init_state: compute buffer (decode) =APP (-zsh)65.96 MB8.50 MB96.83 MB*3ggml_metal_free:deallocatingwhisper_backend_init_gpu:device 0: Metal (type: 1)whisper_backend_init_gpu:found GPUdevice 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init:picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init:usegraphoptimizetruewhisper_backend_init: usingBLAS backendwhisper_init_state: kv selfsize3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: computebuffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type: 1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init: use concurrency= trueggml_metal_init: use graph optimize = truewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize2.36 MBwhisper_init_state: compute buffer (conv)=whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15711:55:19.050419Z2026-05-15T11:55:38.843545Z2026-05-15T11:56:07.397242Z2026-05-15111:56:07.4147922-zshscreenpipe"84181screenpipe*885ec2-user@ip-10-20-...₴86|ec2-user@ip-10-30-...ec2-user@ip-10-...• *8INFO screenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunksINFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=visual_change)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=8724424516320409755, trigger=click)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=click)...
|
NULL
|
-2324710655460953980
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpllolJiminny Tech Day • 6h 4 m leftA100% [8•Fri 15 May 11:56:09DOCKERO ₴1DEV (-zsh)82whisper_init_state:computebuffer(encode)whisper_init_state:compute buffer(cross)=whisper_init_state: compute buffer (decode) =APP (-zsh)65.96 MB8.50 MB96.83 MB*3ggml_metal_free:deallocatingwhisper_backend_init_gpu:device 0: Metal (type: 1)whisper_backend_init_gpu:found GPUdevice 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init:picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init:usegraphoptimizetruewhisper_backend_init: usingBLAS backendwhisper_init_state: kv selfsize3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: computebuffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type: 1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init: use concurrency= trueggml_metal_init: use graph optimize = truewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize2.36 MBwhisper_init_state: compute buffer (conv)=whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15711:55:19.050419Z2026-05-15T11:55:38.843545Z2026-05-15T11:56:07.397242Z2026-05-15111:56:07.4147922-zshscreenpipe"84181screenpipe*885ec2-user@ip-10-20-...₴86|ec2-user@ip-10-30-...ec2-user@ip-10-...• *8INFO screenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunksINFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=visual_change)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=8724424516320409755, trigger=click)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=click)...
|
47829
|
NULL
|
NULL
|
NULL
|
|
47832
|
1699
|
55
|
2026-05-15T08:56:09.570207+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835369570_m2.jpg...
|
PhpStorm
|
faVsco.js – Activity.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
ActivityFllesLaterPhpStormViewINavicareCodeLaravel ActivityFllesLaterPhpStormViewINavicareCodeLaravelKeractorTOOISWindowmelpJiminny...vsStarre• jiminny-x-integrati..8 platform-inner-teamE) Channelsic al-chaoter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# generali#jiminny-bg# platform-tickets# product_launches# random# releases# sofa-office# support# thank-yous# the people of fimi..o- Direct messagesStovan Tomov• Galva Dimitrova De Aneliva Angelovaa Vasil VasilevFV faVsco.js?9 JY-20891-improve-sms-text-relays kProject© InviteUserToTeamAction.php(c) CrmActivityService.ong#reMessagM+ WEBHOOK FILTERING MPLEMENTATIспескалокешукеmоtемatch.php@ RematchActivityOnCrmObjectDetach.phpih External Liorariesv = Scratches and Consoles•Cird•DerProlag;MessageAa• Database ConsolesVAEU« console [EU]A DEAL RISKS (EU)A DI (EU]A EU (EU]v A jiminny@localhostA console [jiminny@localhost& Ul Uiminny@localnost& no local liminny alocalnostA SF [iiminny@localhost)A zoho dev [jiminny@localhost]V & PRODconsole PRODA console 1 [PROD]LDIIPRODDLФA> ₫OAiV APA PROD¿ console PA PRODI© Activity.php x| © UpdateCrmData.phpclass Activity extends Model implementsoublic tunction uodate ctvrvermbatalarrav srecords): vo1di64 A169 ×4 ×102 14 ^ v 653212312124212721312133¿ console 1IPA PRODII2155A console 2 PA PRODI console 3 leA PROD2137I console 4 l0AI PRODd console 5 laAI PRODIIA console 6 loAI PRODI1215921402141A console 7 lGAI PRODIIASTAGING#concole [STAciNGi2143A concole 1 ICTACINGI& uranus [STAGINGI>D Extensionsv MScratchesEphpstorm_shortcuts.txt3 ccratch tytt scratch_1.jsonccratch 2,isonf° scratch 3.isonscratch_4 txtpig scratch_5.phppif scratch_6.phpf" scratch._7.isonf" scratch_8.ison4° stage2.isonE° test<° test.htmllphe tmo.oho6812149Undate the account and onnortunity on the activitv record if nossibleSthis->account id = Saccount->id:2146=683=684if ($this-›stage_id === null && $stage) {2151=685Sthis->stage id = Sstage->id*6862152|16872157|2154688if (Sthis->opportunity id === null && Sopportunity) {E689$this->opportunity id = $opportunity->id:$this->value = Sopportunity->valve:16541if (sthis->stage id === null x& Sstage) <$this->stage_id = $stage->id;if (Sopportunity && Sthis->opportunity_id !== Sopportunity->id) {$this->opportunity_id = $opportunity->id;if (Sopportunity && Sthis->value !== $opportunity->value) {$this->value = Sopportunity->valve:— 00г—662663664— 665=666 v668Always set contact 10 when avallable, regaraless of account 10 status669if (Sthis->contact id === null && Scontact) {Sthis->contact id = Scontact->id:=672othas->saveofelseif (Sstrategy == UpdateCrmDataByStrategy::Account ax $this->account_id = 675Also uodate the parent activity if reauired.checking we don't create=8$this->lead_id = null;if (Sthis->stage &s Sthis->stage-›getType() === Stage::TYPE LEAD) {sthis->stage id = null.$this->save0:Choskod aut IV.20901.imnravo-eme.tovt-rolaue /2/ minutoc saal=custom.logt scratch_8.json= laravel.log4 SF (jiminny@localhost]4 HS_local [jiminny@localhost]A console [PROD] X A console [EU]fiò accounts [EU]fii stages [EU)iiò teams ([EU]ImporbotkecoraingJoo.onp© FixActivitiesOpportunity.php4 console_7 [QAI PRODI4 console [STAGING)do jiminnySELeCt * TrOn acuiity seare titters where acuity seare u011;040 A1 A40 M65 A VSELECT * FROM activities WHERE uuid_to_bin( 8827f672-202d-4162-9d04-73ff5f0566a9') = uuidor uuid_to_bin(*47842446-af51-4bcb-854f-cc6560290101') = uuid;SELECT * FROM crm_configurations WHERE provider = 'hubspot';select * from rate_limits;select * from automated_report_results where media type = 'pdf' and status = 2and id IN (18, 1872);select * from automated_reports where id = 54;SELECT * FROM users WHERE id IN (24623,29443,29613) ;SELECT * FROM automated report results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;select * from text relays where created at > '2026-05-01'# and id IN (32415, 32416):and 10 = 524121select * trom users where team 1d = 2 and emanl uke scort and 10 = 295105SELECT * FROM activities WHERE uuid to bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid: # 79763436SELECT emar provider 1d. COUNT*) as count. GROUP CONCATOd) as ids. GROUP CONCAT(status) as statusesFROM text relavsWHERE eman. oroviden 1d TN 0190202186886404211gezessed8eaobi.0')SELECT id. status. telenhony provider id. created atIWHERE id TN 80028719. 80028846):SELECT id. status. code. email sent at. created at. undatedatIEROM teyt nelavaIWHEPE id TM32415 7241410SELECT id, status, code, sender, recipient, created_atFROM text relaysWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'OpnEp RV cnoated at nesclSELECT id, vuid, status, code, sender, recipient, created at, updated atFROM text relayswucoeuuid = uuid to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656'):• Jiminny lech Day • on 4m len100% 2• Fri 15 May 11:56:09AskJiminnyReportActivityServiceTestReview PR tor ActivityDebug Text Relay Fall+0...Here is the email Stoyan received: From: The Jiminny Team <[EMAIL]>subject: Your text message tailed to senc<[EMAIL]›This is ofly due to uhw message being to long.text message.Please contact support for more information, quoting reference 0626141c-27a6-4d8c-aff8-C8020a2c656 and code 2200Perrect. The email shows• Reference: 0626141c-27a6-4d8c-aff8-7c8020a2c656Code: 2200Code 2200 is REASON CODE SENDER MISMATCH (line 35 in EmailTextRelay.php), which meansThis is a different text relay record than the one we've been looking at (32416 has UUID 0x4CD18652A407AA2DA526870553821366 ). Let me find the record with UUID 9626141c-27a6-4d8c-aff8-7c80.n salSELECT id, uuid, status, code, sender, recipient, created_at, updated_atFROM text_relaysWHERE uuld = uuld to b1n 0626141C-27a6-408c-att8-/c8626azc656 :This will show the actual failed text relay record that triggered the failure email Stovan received.Your included weekly usage quota is exhausted. Using your extra usage. Quota resets May 17, 11:00 AMAsk anvthina (*4Ld es CodolSWE.1GNN Windeurf Toame 666.22 UITC94 spaces...
|
NULL
|
5421570983231557918
|
NULL
|
click
|
ocr
|
NULL
|
ActivityFllesLaterPhpStormViewINavicareCodeLaravel ActivityFllesLaterPhpStormViewINavicareCodeLaravelKeractorTOOISWindowmelpJiminny...vsStarre• jiminny-x-integrati..8 platform-inner-teamE) Channelsic al-chaoter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# generali#jiminny-bg# platform-tickets# product_launches# random# releases# sofa-office# support# thank-yous# the people of fimi..o- Direct messagesStovan Tomov• Galva Dimitrova De Aneliva Angelovaa Vasil VasilevFV faVsco.js?9 JY-20891-improve-sms-text-relays kProject© InviteUserToTeamAction.php(c) CrmActivityService.ong#reMessagM+ WEBHOOK FILTERING MPLEMENTATIспескалокешукеmоtемatch.php@ RematchActivityOnCrmObjectDetach.phpih External Liorariesv = Scratches and Consoles•Cird•DerProlag;MessageAa• Database ConsolesVAEU« console [EU]A DEAL RISKS (EU)A DI (EU]A EU (EU]v A jiminny@localhostA console [jiminny@localhost& Ul Uiminny@localnost& no local liminny alocalnostA SF [iiminny@localhost)A zoho dev [jiminny@localhost]V & PRODconsole PRODA console 1 [PROD]LDIIPRODDLФA> ₫OAiV APA PROD¿ console PA PRODI© Activity.php x| © UpdateCrmData.phpclass Activity extends Model implementsoublic tunction uodate ctvrvermbatalarrav srecords): vo1di64 A169 ×4 ×102 14 ^ v 653212312124212721312133¿ console 1IPA PRODII2155A console 2 PA PRODI console 3 leA PROD2137I console 4 l0AI PRODd console 5 laAI PRODIIA console 6 loAI PRODI1215921402141A console 7 lGAI PRODIIASTAGING#concole [STAciNGi2143A concole 1 ICTACINGI& uranus [STAGINGI>D Extensionsv MScratchesEphpstorm_shortcuts.txt3 ccratch tytt scratch_1.jsonccratch 2,isonf° scratch 3.isonscratch_4 txtpig scratch_5.phppif scratch_6.phpf" scratch._7.isonf" scratch_8.ison4° stage2.isonE° test<° test.htmllphe tmo.oho6812149Undate the account and onnortunity on the activitv record if nossibleSthis->account id = Saccount->id:2146=683=684if ($this-›stage_id === null && $stage) {2151=685Sthis->stage id = Sstage->id*6862152|16872157|2154688if (Sthis->opportunity id === null && Sopportunity) {E689$this->opportunity id = $opportunity->id:$this->value = Sopportunity->valve:16541if (sthis->stage id === null x& Sstage) <$this->stage_id = $stage->id;if (Sopportunity && Sthis->opportunity_id !== Sopportunity->id) {$this->opportunity_id = $opportunity->id;if (Sopportunity && Sthis->value !== $opportunity->value) {$this->value = Sopportunity->valve:— 00г—662663664— 665=666 v668Always set contact 10 when avallable, regaraless of account 10 status669if (Sthis->contact id === null && Scontact) {Sthis->contact id = Scontact->id:=672othas->saveofelseif (Sstrategy == UpdateCrmDataByStrategy::Account ax $this->account_id = 675Also uodate the parent activity if reauired.checking we don't create=8$this->lead_id = null;if (Sthis->stage &s Sthis->stage-›getType() === Stage::TYPE LEAD) {sthis->stage id = null.$this->save0:Choskod aut IV.20901.imnravo-eme.tovt-rolaue /2/ minutoc saal=custom.logt scratch_8.json= laravel.log4 SF (jiminny@localhost]4 HS_local [jiminny@localhost]A console [PROD] X A console [EU]fiò accounts [EU]fii stages [EU)iiò teams ([EU]ImporbotkecoraingJoo.onp© FixActivitiesOpportunity.php4 console_7 [QAI PRODI4 console [STAGING)do jiminnySELeCt * TrOn acuiity seare titters where acuity seare u011;040 A1 A40 M65 A VSELECT * FROM activities WHERE uuid_to_bin( 8827f672-202d-4162-9d04-73ff5f0566a9') = uuidor uuid_to_bin(*47842446-af51-4bcb-854f-cc6560290101') = uuid;SELECT * FROM crm_configurations WHERE provider = 'hubspot';select * from rate_limits;select * from automated_report_results where media type = 'pdf' and status = 2and id IN (18, 1872);select * from automated_reports where id = 54;SELECT * FROM users WHERE id IN (24623,29443,29613) ;SELECT * FROM automated report results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;select * from text relays where created at > '2026-05-01'# and id IN (32415, 32416):and 10 = 524121select * trom users where team 1d = 2 and emanl uke scort and 10 = 295105SELECT * FROM activities WHERE uuid to bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid: # 79763436SELECT emar provider 1d. COUNT*) as count. GROUP CONCATOd) as ids. GROUP CONCAT(status) as statusesFROM text relavsWHERE eman. oroviden 1d TN 0190202186886404211gezessed8eaobi.0')SELECT id. status. telenhony provider id. created atIWHERE id TN 80028719. 80028846):SELECT id. status. code. email sent at. created at. undatedatIEROM teyt nelavaIWHEPE id TM32415 7241410SELECT id, status, code, sender, recipient, created_atFROM text relaysWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'OpnEp RV cnoated at nesclSELECT id, vuid, status, code, sender, recipient, created at, updated atFROM text relayswucoeuuid = uuid to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656'):• Jiminny lech Day • on 4m len100% 2• Fri 15 May 11:56:09AskJiminnyReportActivityServiceTestReview PR tor ActivityDebug Text Relay Fall+0...Here is the email Stoyan received: From: The Jiminny Team <[EMAIL]>subject: Your text message tailed to senc<[EMAIL]›This is ofly due to uhw message being to long.text message.Please contact support for more information, quoting reference 0626141c-27a6-4d8c-aff8-C8020a2c656 and code 2200Perrect. The email shows• Reference: 0626141c-27a6-4d8c-aff8-7c8020a2c656Code: 2200Code 2200 is REASON CODE SENDER MISMATCH (line 35 in EmailTextRelay.php), which meansThis is a different text relay record than the one we've been looking at (32416 has UUID 0x4CD18652A407AA2DA526870553821366 ). Let me find the record with UUID 9626141c-27a6-4d8c-aff8-7c80.n salSELECT id, uuid, status, code, sender, recipient, created_at, updated_atFROM text_relaysWHERE uuld = uuld to b1n 0626141C-27a6-408c-att8-/c8626azc656 :This will show the actual failed text relay record that triggered the failure email Stovan received.Your included weekly usage quota is exhausted. Using your extra usage. Quota resets May 17, 11:00 AMAsk anvthina (*4Ld es CodolSWE.1GNN Windeurf Toame 666.22 UITC94 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47833
|
1698
|
37
|
2026-05-15T08:56:11.457183+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835371457_m1.jpg...
|
PhpStorm
|
faVsco.js – Activity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpllolJiminny Tech Day • 6h 4 m leftA100% [8•Fri 15 May 11:56:11DOCKERO ₴1DEV (-zsh)82whisper_init_state:computebuffer(encode)whisper_init_state:compute buffer(cross)=whisper_init_state: compute buffer (decode) =APP (-zsh)65.96 MB8.50 MB96.83 MB*3ggml_metal_free:deallocatingwhisper_backend_init_gpu:device 0: Metal (type: 1)whisper_backend_init_gpu:found GPUdevice 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init:picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init:usegraphoptimizetruewhisper_backend_init: usingBLAS backendwhisper_init_state: kv selfsize3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: computebuffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type: 1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init: use concurrency= trueggml_metal_init: use graph optimize = truewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize2.36 MBwhisper_init_state: compute buffer (conv)=whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15711:55:19.050419Z2026-05-15T11:55:38.843545Z2026-05-15T11:56:07.397242Z2026-05-15111:56:07.4147922-zshscreenpipe"84181screenpipe*885ec2-user@ip-10-20-... ₴6ec2-user@ip-10-30-…..ec2-user@ip-10-...• *8INFO screenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunksINFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=visual_change)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=8724424516320409755, trigger=click)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=click)...
|
NULL
|
-6565260091981356299
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpllolJiminny Tech Day • 6h 4 m leftA100% [8•Fri 15 May 11:56:11DOCKERO ₴1DEV (-zsh)82whisper_init_state:computebuffer(encode)whisper_init_state:compute buffer(cross)=whisper_init_state: compute buffer (decode) =APP (-zsh)65.96 MB8.50 MB96.83 MB*3ggml_metal_free:deallocatingwhisper_backend_init_gpu:device 0: Metal (type: 1)whisper_backend_init_gpu:found GPUdevice 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init:picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init:usegraphoptimizetruewhisper_backend_init: usingBLAS backendwhisper_init_state: kv selfsize3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: computebuffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type: 1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init: use concurrency= trueggml_metal_init: use graph optimize = truewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize2.36 MBwhisper_init_state: compute buffer (conv)=whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15711:55:19.050419Z2026-05-15T11:55:38.843545Z2026-05-15T11:56:07.397242Z2026-05-15111:56:07.4147922-zshscreenpipe"84181screenpipe*885ec2-user@ip-10-20-... ₴6ec2-user@ip-10-30-…..ec2-user@ip-10-...• *8INFO screenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunksINFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=visual_change)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=8724424516320409755, trigger=click)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=click)...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47834
|
1698
|
38
|
2026-05-15T08:56:15.612649+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835375612_m1.jpg...
|
Firefox
|
[SRD-6848] Sidekick SMS issue - Jira — Work
|
1
|
jiminny.atlassian.net/jira/servicedesk/projects/SR jiminny.atlassian.net/jira/servicedesk/projects/SRD/queues/custom/37/SRD-6848...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp>0 hl 0# Jiminny Tech Day - 6 h 4 m left100%8• Fri 15 May 11:56:15screenpipe"₴4181DOCKER• ₫1DEV (-zsh)82whisper_init_state: computebufferencode)whisper_init_state:compute buffer(cross)whisper_init_state: compute buffer (decode) =APP (-zsh)65.96 MB8.50 MB96.83 MB*3-zshscreenpipe"885ec2-user@ip-10-20-... 86ec2-user@ip-10-30-...ec2-user@ip-10-...ggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type: 1)whisper_backend_init_gpu: found GPUdevice 0: Metal(type: 1, cnt:0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init:picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init: use graph optimizetruewhisper_backend_init: usingBLAS backendwhisper_init_state: kv self size=3.15 MBwhisper_init_state: kv cross size =9.44 MBwhwlwlwlwlPS$19!wl31wlwtFirefoxggmL_metal_1n1t:allocatingggml_metal_init:found device: Apple M1ggml_metal_init:picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init: use graph optimize =truewhisper_backend_init: using BLAS backendwhisper_init_state: kv selfsize3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize2.36 MBwhisper_init_state: compute buffer (conv)=whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)whisper_init_state:compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15711:55:19.050419ZINFOscreenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunks2026-05-15T11:55:38.843545ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=visual_change)2026-05-15T11:56:07.397242ZINFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=8724424516320409755, trigger=click)2026-05-15111:56:07.4147922INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=click)• *8...
|
NULL
|
-9222392708640940527
|
NULL
|
visual_change
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp>0 hl 0# Jiminny Tech Day - 6 h 4 m left100%8• Fri 15 May 11:56:15screenpipe"₴4181DOCKER• ₫1DEV (-zsh)82whisper_init_state: computebufferencode)whisper_init_state:compute buffer(cross)whisper_init_state: compute buffer (decode) =APP (-zsh)65.96 MB8.50 MB96.83 MB*3-zshscreenpipe"885ec2-user@ip-10-20-... 86ec2-user@ip-10-30-...ec2-user@ip-10-...ggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type: 1)whisper_backend_init_gpu: found GPUdevice 0: Metal(type: 1, cnt:0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init:picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init: use graph optimizetruewhisper_backend_init: usingBLAS backendwhisper_init_state: kv self size=3.15 MBwhisper_init_state: kv cross size =9.44 MBwhwlwlwlwlPS$19!wl31wlwtFirefoxggmL_metal_1n1t:allocatingggml_metal_init:found device: Apple M1ggml_metal_init:picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init: use graph optimize =truewhisper_backend_init: using BLAS backendwhisper_init_state: kv selfsize3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize2.36 MBwhisper_init_state: compute buffer (conv)=whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)whisper_init_state:compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15711:55:19.050419ZINFOscreenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunks2026-05-15T11:55:38.843545ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=visual_change)2026-05-15T11:56:07.397242ZINFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=8724424516320409755, trigger=click)2026-05-15111:56:07.4147922INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=click)• *8...
|
47833
|
NULL
|
NULL
|
NULL
|
|
47836
|
1699
|
56
|
2026-05-15T08:56:18.107975+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835378107_m2.jpg...
|
Firefox
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira — Work...
|
1
|
jiminny.atlassian.net/jira/software/c/projects/JY/ jiminny.atlassian.net/jira/software/c/projects/JY/boards/37...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxMistorbookmarksProtllesToolsrTavsco.sProjec FirefoxMistorbookmarksProtllesToolsrTavsco.sProjectJiminny…..sStarre• jiminny-x-integrati..8 platform-inner-team® Channels# ai-chapter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofa-office# support# thank-yous# the people of fimi..? Direct messages8P. Stoyan TomovQ. Galya Dimitrova EP. Aneliya Angelovaa Vasil VasilevWindowmelp79 JY-20891-#re@ MessagProjapplag.VieMessage+ Aa> D Webhook© Account.php© Acuivity.onp© Address.php© AiPrompt.php© AutomatedReport.php© AutomatedReportResultc) calendar.php© Callimport.phpc) CoachingFeedback.php© CoachingFeedback Visitc) CoachinaSection.phg© CoachingSectionCriteric(C) CoachinaSectionCriteric(C) CoachinaSectionFeedbC. CommentAbstract.oho@ Commentinterface.php(C) Contact.oho© Device.php© EmailMessage.php© GenericAiPrompt.php© Group.php©Inbox.php© InboxEmail.php©InboxEmailBatch.php©Invitation.php© JobLog.php© JobTitle.php© Lanquage.php© LanguageDialect.php© Lead.ohr© MobileSetting.php© Model.php© Moment.php@ Nudae.pho© NudgeRun.php@ Opportunitv.ohp©Participant.php(C) Partner.oho©Permission.php(C) PhoneNumber.ohnl© PlaybackTheme.php(C) Plavbook nhn.© PlaybookCategory.php(C) Plavlist nhn(C) Patel imit.nhnl© Region.php© Role.php© RoleChangeEvent.php© ScopeGroup.php(e) Coccion nhnPlatform Sprint 4 Q2 - Platform Te[SRD-6848] Sidekick SMS issu XUsage | WindsurfSRD-6853) Moxso - Potential deaPipelines - jiminny/appFeed - jiminny - SentryWY-209061 Review of Pioedrive SP Pipedrive API Reference and Docupipedrive/client-php: Pipedrive APM Fwd: Your text message failed to si• Pull requests • jiminny/appLL Now Tah©jiminny.atlassian.net/ira/servicedesk/projects/SRD/queues/custom/37/SRD-6848O JIMINNY< Back F SRD-6848Normal textQ Search@ For you© Recent# Starred8$ Apps0, Spaces+....Jiminny (New)9 Service-Desk& Queues+...Team PriorityE All open tickets 15@ Unassigned t... [3E Support tea... 5E Raised by me 10E) Assigned to... 2E, Service requ... 418 Platform team 2E Processing +... 10Site reliability... OE New features... OE InfoSec issues 0Ready for Cu... |2E Resolved ti... 999+= View all queues ›# Service requestsA Incidentslil Reports@ Operations# Knowledge Base& Customers@ ChannelsEmail logs< Develoner escalations•: Slack integration& Reporting Center•Write# And this is the email he got after replying to the email:Hello,Wete really sorry but we could not send your text message.This is often due to the message being too long.Please contact support for more information, quoting reference fd2t33ba-a7d2-4b00-9355-a63c47011b70 and code 2000.Best wishes,The Jiminny TeamReportedly, the text message he tried sending was only two words long.Mario and I performed a couple of tests, and despite receiving each reply via email, we both got the same emails as Scott, stating that the messages were not sent. Below are the failuremessages and the result of our testing:Hello,We're really sorry but we could not send your text message.This is often due to the message being too long.Please contact support for more information, quoting reference 10t371bc-0613-472e-a02f-bc892723c13d and code 2200.1 80 libl O l Jiminny Tech Day • 6h 4mleft CA 100% € &• Fri 15 May 11:56:17+ CreateDAsK RoVoD® @• 2In Progressv Details|Assignee@ Lukas KovalikStoyan TomovReporterRaquesti Report a bugKnowledge base View related artic...Priority level(P2 MediumDev TeamPlatform teamOrganizationCanny LinksReward Gateway-EdenredOpen Canny Links> More fields Labels, Time tracking, Type of InfoSec in...> Automation 4 Rule executions> featureOS Open featureOSIntercomShowing 1 out of 1 linked conversations& Scott de Zoeten> Sentry al Linked IssuesCreated 2 davs aaoUndated 2 davs aao§ Configure...
|
NULL
|
2788001985380306876
|
NULL
|
click
|
ocr
|
NULL
|
FirefoxMistorbookmarksProtllesToolsrTavsco.sProjec FirefoxMistorbookmarksProtllesToolsrTavsco.sProjectJiminny…..sStarre• jiminny-x-integrati..8 platform-inner-team® Channels# ai-chapter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofa-office# support# thank-yous# the people of fimi..? Direct messages8P. Stoyan TomovQ. Galya Dimitrova EP. Aneliya Angelovaa Vasil VasilevWindowmelp79 JY-20891-#re@ MessagProjapplag.VieMessage+ Aa> D Webhook© Account.php© Acuivity.onp© Address.php© AiPrompt.php© AutomatedReport.php© AutomatedReportResultc) calendar.php© Callimport.phpc) CoachingFeedback.php© CoachingFeedback Visitc) CoachinaSection.phg© CoachingSectionCriteric(C) CoachinaSectionCriteric(C) CoachinaSectionFeedbC. CommentAbstract.oho@ Commentinterface.php(C) Contact.oho© Device.php© EmailMessage.php© GenericAiPrompt.php© Group.php©Inbox.php© InboxEmail.php©InboxEmailBatch.php©Invitation.php© JobLog.php© JobTitle.php© Lanquage.php© LanguageDialect.php© Lead.ohr© MobileSetting.php© Model.php© Moment.php@ Nudae.pho© NudgeRun.php@ Opportunitv.ohp©Participant.php(C) Partner.oho©Permission.php(C) PhoneNumber.ohnl© PlaybackTheme.php(C) Plavbook nhn.© PlaybookCategory.php(C) Plavlist nhn(C) Patel imit.nhnl© Region.php© Role.php© RoleChangeEvent.php© ScopeGroup.php(e) Coccion nhnPlatform Sprint 4 Q2 - Platform Te[SRD-6848] Sidekick SMS issu XUsage | WindsurfSRD-6853) Moxso - Potential deaPipelines - jiminny/appFeed - jiminny - SentryWY-209061 Review of Pioedrive SP Pipedrive API Reference and Docupipedrive/client-php: Pipedrive APM Fwd: Your text message failed to si• Pull requests • jiminny/appLL Now Tah©jiminny.atlassian.net/ira/servicedesk/projects/SRD/queues/custom/37/SRD-6848O JIMINNY< Back F SRD-6848Normal textQ Search@ For you© Recent# Starred8$ Apps0, Spaces+....Jiminny (New)9 Service-Desk& Queues+...Team PriorityE All open tickets 15@ Unassigned t... [3E Support tea... 5E Raised by me 10E) Assigned to... 2E, Service requ... 418 Platform team 2E Processing +... 10Site reliability... OE New features... OE InfoSec issues 0Ready for Cu... |2E Resolved ti... 999+= View all queues ›# Service requestsA Incidentslil Reports@ Operations# Knowledge Base& Customers@ ChannelsEmail logs< Develoner escalations•: Slack integration& Reporting Center•Write# And this is the email he got after replying to the email:Hello,Wete really sorry but we could not send your text message.This is often due to the message being too long.Please contact support for more information, quoting reference fd2t33ba-a7d2-4b00-9355-a63c47011b70 and code 2000.Best wishes,The Jiminny TeamReportedly, the text message he tried sending was only two words long.Mario and I performed a couple of tests, and despite receiving each reply via email, we both got the same emails as Scott, stating that the messages were not sent. Below are the failuremessages and the result of our testing:Hello,We're really sorry but we could not send your text message.This is often due to the message being too long.Please contact support for more information, quoting reference 10t371bc-0613-472e-a02f-bc892723c13d and code 2200.1 80 libl O l Jiminny Tech Day • 6h 4mleft CA 100% € &• Fri 15 May 11:56:17+ CreateDAsK RoVoD® @• 2In Progressv Details|Assignee@ Lukas KovalikStoyan TomovReporterRaquesti Report a bugKnowledge base View related artic...Priority level(P2 MediumDev TeamPlatform teamOrganizationCanny LinksReward Gateway-EdenredOpen Canny Links> More fields Labels, Time tracking, Type of InfoSec in...> Automation 4 Rule executions> featureOS Open featureOSIntercomShowing 1 out of 1 linked conversations& Scott de Zoeten> Sentry al Linked IssuesCreated 2 davs aaoUndated 2 davs aao§ Configure...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47835
|
1698
|
39
|
2026-05-15T08:56:18.107981+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835378107_m1.jpg...
|
Firefox
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira — Work...
|
1
|
jiminny.atlassian.net/jira/software/c/projects/JY/ jiminny.atlassian.net/jira/software/c/projects/JY/boards/37...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpllolJiminny Tech Day • 6h 4 m leftA100% [8•Fri 15 May 11:56:17DOCKERO ₴1DEV (-zsh)82whisper_init_state:computebuffer(encode)whisper_init_state:compute buffer(cross)=whisper_init_state: compute buffer (decode) =APP (-zsh)65.96 MB8.50 MB96.83 MB*3ggml_metal_free:deallocatingwhisper_backend_init_gpu:device 0: Metal (type: 1)whisper_backend_init_gpu:found GPUdevice 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init:picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init:usegraphoptimizetruewhisper_backend_init: usingBLAS backendwhisper_init_state: kv selfsize3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: computebuffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type: 1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init: use concurrency= trueggml_metal_init: use graph optimize = truewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize2.36 MBwhisper_init_state: compute buffer (conv)=whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15711:55:19.050419Z2026-05-15T11:55:38.843545Z2026-05-15T11:56:07.397242Z2026-05-15111:56:07.4147922-zshscreenpipe"84181screenpipe*885ec2-user@ip-10-20-... ₴6ec2-user@ip-10-30-…..ec2-user@ip-10-...• *8INFO screenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunksINFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=visual_change)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=8724424516320409755, trigger=click)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=click)...
|
NULL
|
2910013329176716349
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpllolJiminny Tech Day • 6h 4 m leftA100% [8•Fri 15 May 11:56:17DOCKERO ₴1DEV (-zsh)82whisper_init_state:computebuffer(encode)whisper_init_state:compute buffer(cross)=whisper_init_state: compute buffer (decode) =APP (-zsh)65.96 MB8.50 MB96.83 MB*3ggml_metal_free:deallocatingwhisper_backend_init_gpu:device 0: Metal (type: 1)whisper_backend_init_gpu:found GPUdevice 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init:picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init:usegraphoptimizetruewhisper_backend_init: usingBLAS backendwhisper_init_state: kv selfsize3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: computebuffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type: 1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init: use concurrency= trueggml_metal_init: use graph optimize = truewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize2.36 MBwhisper_init_state: compute buffer (conv)=whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-15711:55:19.050419Z2026-05-15T11:55:38.843545Z2026-05-15T11:56:07.397242Z2026-05-15111:56:07.4147922-zshscreenpipe"84181screenpipe*885ec2-user@ip-10-20-... ₴6ec2-user@ip-10-30-…..ec2-user@ip-10-...• *8INFO screenpipe_audio::audio_manager::manager: reconciliation: transcribed 50 orphaned chunksINFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=visual_change)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=8724424516320409755, trigger=click)INFO screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 2 (hash=8724424516320409755, trigger=click)...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47837
|
1699
|
57
|
2026-05-15T08:56:19.600170+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835379600_m2.jpg...
|
Firefox
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira — Work...
|
1
|
jiminny.atlassian.net/jira/software/c/projects/JY/ jiminny.atlassian.net/jira/software/c/projects/JY/boards/37...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Space navigation
Space navigation
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team
Board actions
Board actions
Enterprise Stability Issues 🤕
Enterprise Stability Issues 🤕
Board actions
Board actions
Processing Team
Processing Team
Board actions
Board actions
SE Kanban
SE Kanban
Board actions
Board actions
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.05905826,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"bounds":{"left":0.31266624,"top":0.07861133,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Space navigation","depth":10,"bounds":{"left":0.31266624,"top":0.15522745,"width":0.037898935,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Space navigation","depth":11,"bounds":{"left":0.31266624,"top":0.15522745,"width":0.037898935,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"bounds":{"left":0.30601728,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"bounds":{"left":0.31117022,"top":0.06344773,"width":0.039727394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"bounds":{"left":0.3179854,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"bounds":{"left":0.3231383,"top":0.06344773,"width":0.044215426,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"bounds":{"left":0.33128324,"top":0.057861134,"width":0.029421542,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":11,"bounds":{"left":0.5159575,"top":0.06264964,"width":0.24268617,"height":0.015961692},"on_screen":true,"help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"bounds":{"left":0.7669548,"top":0.057861134,"width":0.030086435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"bounds":{"left":0.77825797,"top":0.06384677,"width":0.014793883,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"bounds":{"left":0.91223407,"top":0.057861134,"width":0.035904255,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"bounds":{"left":0.92353725,"top":0.06384677,"width":0.020611702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"bounds":{"left":0.9494681,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"bounds":{"left":0.954621,"top":0.06344773,"width":0.027759308,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"bounds":{"left":0.96143615,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"bounds":{"left":0.9665891,"top":0.06344773,"width":0.010139627,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"bounds":{"left":0.9734042,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.97855717,"top":0.06344773,"width":0.017952127,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.98537236,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"bounds":{"left":0.99052525,"top":0.06344773,"width":0.009474754,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"bounds":{"left":0.30601728,"top":0.09976058,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"bounds":{"left":0.31665558,"top":0.10574621,"width":0.01662234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"bounds":{"left":0.30601728,"top":0.12529927,"width":0.071476065,"height":0.025538707},"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":"Recent","depth":15,"bounds":{"left":0.31665558,"top":0.13128492,"width":0.015458777,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Starred","depth":12,"bounds":{"left":0.30601728,"top":0.15083799,"width":0.071476065,"height":0.025538707},"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":"Starred","depth":15,"bounds":{"left":0.31665558,"top":0.15682362,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","depth":12,"bounds":{"left":0.30601728,"top":0.1763767,"width":0.071476065,"height":0.025538707},"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":"Apps","depth":15,"bounds":{"left":0.31665558,"top":0.18236233,"width":0.011635638,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Apps","depth":13,"bounds":{"left":0.37549868,"top":0.17956904,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Apps","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Spaces","depth":12,"bounds":{"left":0.30601728,"top":0.2019154,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Spaces","depth":15,"bounds":{"left":0.31665558,"top":0.20790103,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create space","depth":13,"bounds":{"left":0.35887632,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create space","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for spaces","depth":13,"bounds":{"left":0.36818483,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for spaces","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recent","depth":16,"bounds":{"left":0.31200132,"top":0.23423783,"width":0.013464096,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny (New)","depth":17,"bounds":{"left":0.31000665,"top":0.2529928,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny (New)","depth":20,"bounds":{"left":0.32064494,"top":0.25897846,"width":0.032081116,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Jiminny (New)","depth":18,"bounds":{"left":0.31133643,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXMenuButton","text":"Create board","depth":18,"bounds":{"left":0.35887632,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create board","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Jiminny (New)","depth":18,"bounds":{"left":0.36818483,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Jiminny (New)","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform Team","depth":19,"bounds":{"left":0.31399602,"top":0.27853152,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Team","depth":22,"bounds":{"left":0.3246343,"top":0.28451717,"width":0.032247342,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.37549868,"top":0.28172386,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Capture Team","depth":19,"bounds":{"left":0.31399602,"top":0.30407023,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Capture Team","depth":22,"bounds":{"left":0.3246343,"top":0.31005585,"width":0.03125,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.37549868,"top":0.30726257,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Enterprise Stability Issues 🤕","depth":19,"bounds":{"left":0.31399602,"top":0.32960895,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enterprise Stability Issues 🤕","depth":22,"bounds":{"left":0.3246343,"top":0.33559456,"width":0.050531916,"height":0.030726258},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.37549868,"top":0.33280128,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Processing Team","depth":19,"bounds":{"left":0.31399602,"top":0.35514766,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Processing Team","depth":22,"bounds":{"left":0.3246343,"top":0.36113328,"width":0.038231384,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.37549868,"top":0.35834,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SE Kanban","depth":19,"bounds":{"left":0.31399602,"top":0.38068634,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SE Kanban","depth":22,"bounds":{"left":0.3246343,"top":0.386672,"width":0.024102394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.37549868,"top":0.38387868,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service-Desk","depth":17,"bounds":{"left":0.31000665,"top":0.40622506,"width":0.0674867,"height":0.025538707},"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":"Service-Desk","depth":20,"bounds":{"left":0.32064494,"top":0.4122107,"width":0.03025266,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Service-Desk","depth":18,"bounds":{"left":0.37682846,"top":0.4094174,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Service-Desk","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-1768091186342007501
|
1014752115402166286
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Space navigation
Space navigation
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team
Board actions
Board actions
Enterprise Stability Issues 🤕
Enterprise Stability Issues 🤕
Board actions
Board actions
Processing Team
Processing Team
Board actions
Board actions
SE Kanban
SE Kanban
Board actions
Board actions
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk...
|
47836
|
NULL
|
NULL
|
NULL
|
|
47838
|
1698
|
40
|
2026-05-15T08:56:20.827125+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835380827_m1.jpg...
|
Firefox
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira — Work...
|
1
|
jiminny.atlassian.net/jira/software/c/projects/JY/ jiminny.atlassian.net/jira/software/c/projects/JY/boards/37...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
6998670694004651521
|
-1982414211873080179
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app...
|
47835
|
NULL
|
NULL
|
NULL
|
|
47839
|
1699
|
58
|
2026-05-15T08:56:20.842923+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835380842_m2.jpg...
|
Firefox
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira — Work...
|
1
|
jiminny.atlassian.net/jira/software/c/projects/JY/ jiminny.atlassian.net/jira/software/c/projects/JY/boards/37...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.05905826,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-5109490550553692626
|
-1991421411127829363
|
click
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
47840
|
1699
|
59
|
2026-05-15T08:56:22.664584+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-15/1778 /Users/lukas/.screenpipe/data/data/2026-05-15/1778835382664_m2.jpg...
|
Firefox
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira — Work...
|
1
|
jiminny.atlassian.net/jira/software/c/projects/JY/ jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20891...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Space navigation
Space navigation
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team
Board actions
Board actions
Enterprise Stability Issues 🤕
Enterprise Stability Issues 🤕
Board actions
Board actions
Processing Team
Processing Team
Board actions
Board actions
SE Kanban
SE Kanban
Board actions
Board actions
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
More spaces
More spaces
Filters...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.2897274,"top":0.05905826,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.09577015,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.22240691,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.2357048,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6853] Moxso - Potential deal stages bug - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.16121309,"width":0.09158909,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.22240691,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2357048,"top":0.22665602,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":4,"bounds":{"left":0.22240691,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20906] Review of Pipedrive SDK - Jira","depth":5,"bounds":{"left":0.2357048,"top":0.25937748,"width":0.07413564,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipedrive API Reference and Documentation","depth":4,"bounds":{"left":0.22240691,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipedrive API Reference and Documentation","depth":5,"bounds":{"left":0.2357048,"top":0.29209897,"width":0.07679521,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":4,"bounds":{"left":0.22240691,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"pipedrive/client-php: Pipedrive API client for PHP","depth":5,"bounds":{"left":0.2357048,"top":0.32482043,"width":0.08543883,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.22240691,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fwd: Your text message failed to send - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.2357048,"top":0.3575419,"width":0.14095744,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.22240691,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2357048,"top":0.39026338,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.2252327,"top":0.41340783,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2252327,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.23620346,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.24734043,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.2584774,"top":0.97007185,"width":0.010638298,"height":0.025538707},"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.26961437,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"bounds":{"left":0.31266624,"top":0.07861133,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"bounds":{"left":0.31266624,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"bounds":{"left":0.31266624,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"bounds":{"left":0.31266624,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Space navigation","depth":10,"bounds":{"left":0.31266624,"top":0.15522745,"width":0.037898935,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Space navigation","depth":11,"bounds":{"left":0.31266624,"top":0.15522745,"width":0.037898935,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"bounds":{"left":0.30601728,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"bounds":{"left":0.31117022,"top":0.06344773,"width":0.039727394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"bounds":{"left":0.3179854,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"bounds":{"left":0.3231383,"top":0.06344773,"width":0.044215426,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"bounds":{"left":0.33128324,"top":0.057861134,"width":0.029421542,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":11,"bounds":{"left":0.5159575,"top":0.06264964,"width":0.24268617,"height":0.015961692},"on_screen":true,"help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"bounds":{"left":0.7669548,"top":0.057861134,"width":0.030086435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"bounds":{"left":0.77825797,"top":0.06384677,"width":0.014793883,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"bounds":{"left":0.91223407,"top":0.057861134,"width":0.035904255,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"bounds":{"left":0.92353725,"top":0.06384677,"width":0.020611702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"bounds":{"left":0.9494681,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"bounds":{"left":0.954621,"top":0.06344773,"width":0.027759308,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"bounds":{"left":0.96143615,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"bounds":{"left":0.9665891,"top":0.06344773,"width":0.010139627,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"bounds":{"left":0.9734042,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.97855717,"top":0.06344773,"width":0.017952127,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.98537236,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"bounds":{"left":0.99052525,"top":0.06344773,"width":0.009474754,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"bounds":{"left":0.30601728,"top":0.09976058,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"bounds":{"left":0.31665558,"top":0.10574621,"width":0.01662234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"bounds":{"left":0.30601728,"top":0.12529927,"width":0.071476065,"height":0.025538707},"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":"Recent","depth":15,"bounds":{"left":0.31665558,"top":0.13128492,"width":0.015458777,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Starred","depth":12,"bounds":{"left":0.30601728,"top":0.15083799,"width":0.071476065,"height":0.025538707},"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":"Starred","depth":15,"bounds":{"left":0.31665558,"top":0.15682362,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","depth":12,"bounds":{"left":0.30601728,"top":0.1763767,"width":0.071476065,"height":0.025538707},"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":"Apps","depth":15,"bounds":{"left":0.31665558,"top":0.18236233,"width":0.011635638,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Apps","depth":13,"bounds":{"left":0.37549868,"top":0.17956904,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Apps","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Spaces","depth":12,"bounds":{"left":0.30601728,"top":0.2019154,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Spaces","depth":15,"bounds":{"left":0.31665558,"top":0.20790103,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create space","depth":13,"bounds":{"left":0.35887632,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create space","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for spaces","depth":13,"bounds":{"left":0.36818483,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for spaces","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recent","depth":16,"bounds":{"left":0.31200132,"top":0.23423783,"width":0.013464096,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny (New)","depth":17,"bounds":{"left":0.31000665,"top":0.2529928,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny (New)","depth":20,"bounds":{"left":0.32064494,"top":0.25897846,"width":0.032081116,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Jiminny (New)","depth":18,"bounds":{"left":0.31133643,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXMenuButton","text":"Create board","depth":18,"bounds":{"left":0.35887632,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create board","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Jiminny (New)","depth":18,"bounds":{"left":0.36818483,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Jiminny (New)","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform Team","depth":19,"bounds":{"left":0.31399602,"top":0.27853152,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Team","depth":22,"bounds":{"left":0.3246343,"top":0.28451717,"width":0.032247342,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.37549868,"top":0.28172386,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Capture Team","depth":19,"bounds":{"left":0.31399602,"top":0.30407023,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Capture Team","depth":22,"bounds":{"left":0.3246343,"top":0.31005585,"width":0.03125,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.37549868,"top":0.30726257,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Enterprise Stability Issues 🤕","depth":19,"bounds":{"left":0.31399602,"top":0.32960895,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enterprise Stability Issues 🤕","depth":22,"bounds":{"left":0.3246343,"top":0.33559456,"width":0.050531916,"height":0.030726258},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.37549868,"top":0.33280128,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Processing Team","depth":19,"bounds":{"left":0.31399602,"top":0.35514766,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Processing Team","depth":22,"bounds":{"left":0.3246343,"top":0.36113328,"width":0.038231384,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.37549868,"top":0.35834,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SE Kanban","depth":19,"bounds":{"left":0.31399602,"top":0.38068634,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SE Kanban","depth":22,"bounds":{"left":0.3246343,"top":0.386672,"width":0.024102394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.37549868,"top":0.38387868,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service-Desk","depth":17,"bounds":{"left":0.31000665,"top":0.40622506,"width":0.0674867,"height":0.025538707},"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":"Service-Desk","depth":20,"bounds":{"left":0.32064494,"top":0.4122107,"width":0.03025266,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Service-Desk","depth":18,"bounds":{"left":0.37682846,"top":0.4094174,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Service-Desk","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More spaces","depth":17,"bounds":{"left":0.31000665,"top":0.43176377,"width":0.0674867,"height":0.025538707},"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":"More spaces","depth":20,"bounds":{"left":0.32064494,"top":0.43774942,"width":0.028756648,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":12,"bounds":{"left":0.30601728,"top":0.45730248,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
4533341604389847905
|
2167656027822968844
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Close tab
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
Usage | Windsurf
Usage | Windsurf
[SRD-6853] Moxso - Potential deal stages bug - Jira
[SRD-6853] Moxso - Potential deal stages bug - Jira
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
[JY-20906] Review of Pipedrive SDK - Jira
[JY-20906] Review of Pipedrive SDK - Jira
Pipedrive API Reference and Documentation
Pipedrive API Reference and Documentation
pipedrive/client-php: Pipedrive API client for PHP
pipedrive/client-php: Pipedrive API client for PHP
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Fwd: Your text message failed to send - [EMAIL] - Jiminny Mail
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Space navigation
Space navigation
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team
Board actions
Board actions
Enterprise Stability Issues 🤕
Enterprise Stability Issues 🤕
Board actions
Board actions
Processing Team
Processing Team
Board actions
Board actions
SE Kanban
SE Kanban
Board actions
Board actions
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
More spaces
More spaces
Filters...
|
47839
|
NULL
|
NULL
|
NULL
|