Skip to content

Commit 8f47d1c

Browse files
committed
Adds detail report around requests made by AI bots (#23793)
* Adds archiving for new report(s) * Add API methods for new report * Add report classes * Move AI Agent reports to bottom * Add system tests for new report * Adds UI tests for new report * updates expected UI test files * fix other tests * do not double count acquired visits * remove explicit plugin loading from ui tests * updates expected UI test file
1 parent f77d99f commit 8f47d1c

File tree

62 files changed

+1716
-41
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1716
-41
lines changed

config/global.ini.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,11 @@
632632
; maximum number of rows for the Products reports
633633
datatable_archiving_maximum_rows_products = 10000
634634

635+
; maximum number of AI Assistants listed in Bot Tracking reports
636+
datatable_archiving_maximum_rows_bots = 250
637+
; maximum number of page/document rows listed per AI Assistant in Bot Tracking reports
638+
datatable_archiving_maximum_rows_subtable_bots = 250
639+
635640
; maximum number of rows for other tables (Providers, User settings configurations)
636641
datatable_archiving_maximum_rows_standard = 500
637642

plugins/AIAgents/Reports/Get.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ protected function init()
3333
$this->name = Piwik::translate('AIAgents_AIAgentVisits');
3434
$this->categoryId = 'AIAgents_AIAssistants';
3535
$this->subcategoryId = 'General_Overview';
36-
$this->order = 10;
36+
$this->order = 90;
3737

3838
$this->processedMetrics = [
3939
new AIAgentMetric(new AverageTimeOnSite(), API::AI_AGENT_COLUMN_SUFFIX),
@@ -66,14 +66,14 @@ public function configureWidgets(WidgetsList $widgetsList, ReportWidgetFactory $
6666
->setName('AIAgents_WidgetGraphAIAgents')
6767
->forceViewDataTable(Evolution::ID)
6868
->setAction('getEvolutionGraph')
69-
->setOrder(1)
69+
->setOrder(90)
7070
);
7171

7272
$widgetsList->addWidgetConfig(
7373
$factory->createWidget()
7474
->forceViewDataTable(Sparklines::ID)
7575
->setName('AIAgents_WidgetOverviewAIAgents')
76-
->setOrder(2)
76+
->setOrder(91)
7777
);
7878
}
7979

plugins/AIAgents/tests/UI/AIAgents_spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('AIAgents', function () {
1717
await page.waitForNetworkIdle();
1818

1919
const widgets = await page.$$('.matomo-widget');
20-
expect(widgets.length).to.equal(2);
20+
expect(widgets.length).to.equal(3);
2121
});
2222

2323
it('should show the AI assistants report menu items', async function () {
14.3 KB
Loading

plugins/BotTracking/API.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
/**
4+
* Matomo - free/libre analytics platform
5+
*
6+
* @link https://matomo.org
7+
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Piwik\Plugins\BotTracking;
13+
14+
use Piwik\Archive;
15+
use Piwik\DataTable;
16+
use Piwik\DataTable\DataTableInterface;
17+
use Piwik\Piwik;
18+
19+
class API extends \Piwik\Plugin\API
20+
{
21+
/**
22+
* Returns a report about AI assistants crawling your site and how many hits each one generates. Depending on the provided secondary dimension
23+
* the subtable will either contain all requested page urls or document urls.
24+
*
25+
* @param string|int|int[] $idSite
26+
* @param null|'pages'|'documents' $secondaryDimension can be either `pages` (default) or `documents`
27+
* @return DataTable|DataTable\Map
28+
*/
29+
public function getAIAssistantRequests($idSite, string $period, string $date, bool $expanded = false, bool $flat = false, ?string $secondaryDimension = null): DataTableInterface
30+
{
31+
Piwik::checkUserHasViewAccess($idSite);
32+
33+
$archiveName = Archiver::AI_ASSISTANTS_PAGES_RECORD;
34+
35+
if ($secondaryDimension === 'documents') {
36+
$archiveName = Archiver::AI_ASSISTANTS_DOCUMENTS_RECORD;
37+
}
38+
39+
$dataTable = Archive::createDataTableFromArchive($archiveName, $idSite, $period, $date, '', $expanded, $flat);
40+
41+
// When flattening a report, remove all main table rows, where no subtable exists
42+
if ($flat) {
43+
$dataTable->filter(function (DataTable $table) {
44+
foreach ($table->getRows() as $key => $row) {
45+
if (!$row->getIdSubDataTable()) {
46+
$table->deleteRow($key);
47+
}
48+
}
49+
});
50+
}
51+
52+
return $dataTable;
53+
}
54+
55+
/**
56+
* @param string|int|int[] $idSite
57+
* @return DataTable|DataTable\Map
58+
*/
59+
public function getPageUrlsForAIAssistant($idSite, string $period, string $date, int $idSubtable): DataTableInterface
60+
{
61+
Piwik::checkUserHasViewAccess($idSite);
62+
63+
return Archive::createDataTableFromArchive(Archiver::AI_ASSISTANTS_PAGES_RECORD, $idSite, $period, $date, '', false, false, $idSubtable);
64+
}
65+
66+
/**
67+
* @param string|int|int[] $idSite
68+
* @return DataTable|DataTable\Map
69+
*/
70+
public function getDocumentUrlsForAIAssistant($idSite, string $period, string $date, int $idSubtable): DataTableInterface
71+
{
72+
Piwik::checkUserHasViewAccess($idSite);
73+
74+
return Archive::createDataTableFromArchive(Archiver::AI_ASSISTANTS_DOCUMENTS_RECORD, $idSite, $period, $date, '', false, false, $idSubtable);
75+
}
76+
}

plugins/BotTracking/Archiver.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/**
4+
* Matomo - free/libre analytics platform
5+
*
6+
* @link https://matomo.org
7+
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Piwik\Plugins\BotTracking;
13+
14+
class Archiver extends \Piwik\Plugin\Archiver
15+
{
16+
public const AI_ASSISTANTS_PAGES_RECORD = 'BotTracking_AIAssistantsPages';
17+
public const AI_ASSISTANTS_DOCUMENTS_RECORD = 'BotTracking_AIAssistantsDocuments';
18+
19+
public static function shouldRunEvenWhenNoVisits(): bool
20+
{
21+
return true;
22+
}
23+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/**
4+
* Matomo - free/libre analytics platform
5+
*
6+
* @link https://matomo.org
7+
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Piwik\Plugins\BotTracking\Columns;
13+
14+
use Piwik\Columns\Dimension;
15+
16+
class AIAssistantName extends Dimension
17+
{
18+
protected $nameSingular = 'BotTracking_ColumnAIAssistantName';
19+
protected $type = self::TYPE_TEXT;
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/**
4+
* Matomo - free/libre analytics platform
5+
*
6+
* @link https://matomo.org
7+
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Piwik\Plugins\BotTracking\Columns;
13+
14+
use Piwik\Columns\Dimension;
15+
16+
class DocumentUrl extends Dimension
17+
{
18+
protected $nameSingular = 'BotTracking_DocumentUrl';
19+
protected $type = self::TYPE_URL;
20+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
/**
4+
* Matomo - free/libre analytics platform
5+
*
6+
* @link https://matomo.org
7+
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Piwik\Plugins\BotTracking\Columns\Metrics;
13+
14+
use Piwik\Columns\Dimension;
15+
use Piwik\Metrics\Formatter;
16+
use Piwik\Piwik;
17+
use Piwik\Plugin\AggregatedMetric;
18+
use Piwik\Plugins\BotTracking\Metrics;
19+
20+
class AcquiredVisits extends AggregatedMetric
21+
{
22+
public function getName()
23+
{
24+
return Metrics::COLUMN_ACQUIRED_VISITS;
25+
}
26+
27+
public function getTranslatedName()
28+
{
29+
return Piwik::translate('BotTracking_ColumnAcquiredVisits');
30+
}
31+
32+
public function getDocumentation()
33+
{
34+
return Piwik::translate('BotTracking_ColumnAcquiredVisitsDocumentation');
35+
}
36+
37+
public function format($value, Formatter $formatter)
38+
{
39+
return $formatter->getPrettyNumber($value);
40+
}
41+
42+
public function getSemanticType(): ?string
43+
{
44+
return Dimension::TYPE_NUMBER;
45+
}
46+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
/**
4+
* Matomo - free/libre analytics platform
5+
*
6+
* @link https://matomo.org
7+
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Piwik\Plugins\BotTracking\Columns\Metrics;
13+
14+
use Piwik\Columns\Dimension;
15+
use Piwik\Metrics\Formatter;
16+
use Piwik\Piwik;
17+
use Piwik\Plugin\AggregatedMetric;
18+
use Piwik\Plugins\BotTracking\Metrics;
19+
20+
class DocumentRequests extends AggregatedMetric
21+
{
22+
public function getName()
23+
{
24+
return Metrics::COLUMN_DOCUMENT_REQUESTS;
25+
}
26+
27+
public function getTranslatedName()
28+
{
29+
return Piwik::translate('BotTracking_ColumnDocumentRequests');
30+
}
31+
32+
public function getDocumentation()
33+
{
34+
return Piwik::translate('BotTracking_ColumnDocumentRequestsDocumentation');
35+
}
36+
37+
public function format($value, Formatter $formatter)
38+
{
39+
return $formatter->getPrettyNumber($value);
40+
}
41+
42+
public function getSemanticType(): ?string
43+
{
44+
return Dimension::TYPE_NUMBER;
45+
}
46+
}

0 commit comments

Comments
 (0)