Cách ngăn Plausible ghi nhận lượt xem trang khi gặp lỗi 404 trong Laravel

Tôi thực sự thích sử dụng Plausible để phân tích dữ liệu. Google Analytics (sau đây gọi tắt là GA) đối với tôi có phần "hơi quá", nhất là khi PageSpeed Insights cứ liên tục nhắc tôi rằng script của GA "quá nặng" (thật trớ trêu).

Một trong những điều khiến tôi ấn tượng là tài liệu hướng dẫn của họ - ngắn gọn, đơn giản nhưng hiệu quả, và tôi đặc biệt thích các hướng dẫn cài đặt/tích hợp (trong đó có nhắc cụ thể đến Laravel, công cụ chính tôi hay dùng, thứ đôi khi lại không hề xuất hiện trong danh sách của các tài liệu tương tự).

Vấn đề với route

Vậy nên với website này, tôi đã dùng package composer vincentbean/laravel-plausible, và việc tích hợp diễn ra khá suôn sẻ. Nhưng thật không may, sau một tháng sử dụng, tôi phát hiện ra một vấn đề - hàng loạt request giả tới các trang và tài nguyên không tồn tại. Điều đó cũng khá dễ hiểu, vì một trong các route là route dạng wildcard như thế này:

Route::get('/{slug}', [PageController::class, 'page'])->where('slug', '^(?!.*\.|^\/(favicon|css|js|storage|build)).*$')->name('page');

Danh sách các request spam

Vậy nên khi danh sách các endpoint này xuất hiện trên dashboard, tôi nghĩ - chuyện nhỏ thôi, cứ loại trừ chúng ra là ổn. Nghe có vẻ là một ý tưởng khá chắc chắn... Nhưng trời ơi, tôi đã lầm... Đây là những gì chờ đợi tôi sau khi đã thêm tất cả các endpoint cơ bản vào danh sách loại trừ:

Danh sách endpoint ngẫu nhiên của các ngân hàng Nga

Khi nhìn thấy danh sách endpoint từ một vài ngân hàng Nga này, tôi hiểu rằng việc lọc tất cả mọi thứ chắc chắn không phải là hướng đi của mình. Vậy nên sau khi tự pha cho mình một ly soda đá, tôi bắt đầu tìm giải pháp ít rắc rối nhất cho vấn đề này, với thay đổi code tối thiểu.

Mục tiêu

Đây về cơ bản là hành vi mà tôi mong muốn:

  1. Kích hoạt event khi package đã được cấu hình;
  2. Kích hoạt event khi trang tồn tại;
  3. Kích hoạt event khi không phải CLI (coi như một điểm cộng thêm, vì nó cũng làm sai lệch số liệu thống kê một chút);

Cách khắc phục

Middleware trong package đã xử lý khá tốt điểm 1, nhưng điểm 2 và 3 vẫn chưa được giải quyết. Vậy nên sau khi xem xét đoạn Middleware này - vốn cũng khá trống trải như phần lớn các middleware khác - tôi đã cải tiến đoạn code của middleware theo cách sau:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;
use VincentBean\Plausible\Facades\PlausibleEvent;

class TrackPlausiblePageviews
{
    public function handle(Request $request, Closure $next): mixed
    {
        $response = $next($request);

        if (config('plausible.tracking_domain') !== null 
						&& $response->status() !== Response::HTTP_NOT_FOUND 
						&& is_string($request->userAgent())
            && !in_array($request->userAgent(), config('plausible.ignore_agents'))) {
            PlausibleEvent::fire('pageview');
        }

        return $response;
    }

Vậy nên, đầu tiên, tôi vẫn kiểm tra xem mình đã cấu hình tracking_domain hay chưa, vì nếu chưa thì cũng chẳng cần xử lý tiếp event làm gì. Sau đó, tôi sử dụng một tính năng có sẵn của Laravel - ném lỗi 404 khi dùng firstOrFail(). Và cuối cùng, nó kiểm tra User Agent một cách cẩn thận, vì nếu không tôi sẽ bị chính bộ tạo sitemap của mình spam.

Trong config/plausible.php, tôi đã đơn giản thêm các agent gây phiền toái (và đúng vậy, tôi hard-code chúng luôn, vì chúng không thay đổi thường xuyên). Vậy nên đừng ngại thêm cái này vào config của bạn:

	'ignore_agents' => [
        'GuzzleHttp/7'
    ],

Kết luận

Tôi nghĩ ai cũng biết câu "Nếu nó hoạt động, đừng đụng vào". Trong trường hợp cụ thể này, tôi hoàn toàn đồng ý với câu nói đó. Vấn đề của tôi được giải quyết chỉ với vài dòng code, còn ly soda đá của tôi thì vẫn chưa uống hết.

P.S. Gửi đội ngũ Plausible - làm sao để tôi xóa MỘT PHẦN các bản ghi cũ trong Analytics vậy? 😅