#!/usr/bin/env python3 import json import os def generate_dashboard(): json_path = "/opt/ai-os/products/ceo/projects/GLV/reports/seo_raw_data.json" if not os.path.exists(json_path): print(f"Error: {json_path} not found.") return with open(json_path, "r", encoding="utf-8") as f: data = json.load(f) # Output file path out_dir = "/opt/ai-os/products/ceo/projects/GLV/reports" os.makedirs(out_dir, exist_ok=True) out_html_path = os.path.join(out_dir, "glv_seo_dashboard.html") # Serialize raw data for embedding in HTML as JS constant embedded_data_json = json.dumps(data, ensure_ascii=False) html_template = """
Snapshot of GSC + GA4 via Local Analytics API · last 30 days vs prior 30 days
Hệ thống ghi nhận sự kiện chuyển đổi chính thức (Key Events) chưa được bật cờ trong GA4. Báo cáo đang tạm thời sử dụng tổng phiên tương tác (Engaged Sessions) làm chỉ số thay thế.
Fix: GA4 → Admin → Events → Bật cờ "Mark as key event" cho form_submit.
30-day totals with delta vs prior 30 days and a daily sparkline. Position uses inverted color logic – lower rank value = better.
Where visits come from and how channel mix is moving. Stacked area = GA4 sessions by channel daily; right chart = GSC clicks & impressions trend.
GA4 · stacked area, last 30 days
GSC · clicks (lime) & impressions (cyan)
Volume, quality, and the conversion proxy
If branded grows but non-branded is flat, you're winning back people who already know you — not new demand.
High-speed improvement opportunities generated via algorithmic patterns.
Từ khóa đang nằm ở trang 1 nhưng chưa vào top 3. Cần tối ưu nội dung để đẩy top.
Từ khóa ở trang 2 có lượng hiển thị tốt. Bổ sung liên kết nội bộ để đẩy sang trang 1.
Trang hiển thị nhiều nhưng tỷ lệ nhấp thấp. Cần viết lại Title và Meta Description.
Từ khóa có trên 30 hiển thị nhưng chưa nhận được nhấp nào. Kiểm tra Intent từ khóa.
Detailed breakdown of top driving search queries and landing pages.
Lọc theo số lượt nhấp và hiển thị.
Lọc theo đường dẫn URL.