Skip to content

Commit c67cd7e

Browse files
committed
Add analytics_id config: inject Google Analytics into dashboard pages
Node owners can set analytics_id in YAML config to automatically inject the GA4 gtag.js snippet into all HTML pages served by the dashboard. No injection when unset (default).
1 parent 6271eaf commit c67cd7e

5 files changed

Lines changed: 42 additions & 0 deletions

File tree

config/c2pool_mainnet.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,4 @@ storage_save_interval: 300 # Periodic sharechain save interval (seconds)
9696

9797
# ─── Web Dashboard ──────────────────────────────────────────────────────────
9898
dashboard_dir: "web-static" # Static dashboard directory (relative or absolute)
99+
# analytics_id: "G-XXXXXXXXXX" # Google Analytics measurement ID (optional)

config/c2pool_testnet.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ cors_origin: "*" # Access-Control-Allow-Origin header
5858

5959
# ─── Web Dashboard ──────────────────────────────────────────────────────────
6060
dashboard_dir: "web-static" # Static dashboard directory (relative or absolute)
61+
# analytics_id: "G-XXXXXXXXXX" # Google Analytics measurement ID (optional)
6162

6263
# ─── DOGE Merged Mining ─────────────────────────────────────────────────────
6364
doge_testnet4alpha: true # Use testnet4alpha chain params (not testnet3)

src/c2pool/c2pool_refactored.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,9 @@ int main(int argc, char* argv[]) {
502502
// Dashboard directory (web-static/ by default, relative to CWD)
503503
std::string dashboard_dir = "web-static";
504504

505+
// Google Analytics measurement ID (e.g. G-XXXXXXXXXX)
506+
std::string analytics_id;
507+
505508
// Optional encrypted authority message_data blob for local V36 shares.
506509
std::string operator_message_blob_hex;
507510

@@ -1087,6 +1090,8 @@ int main(int argc, char* argv[]) {
10871090
storage_save_interval = cfg["storage_save_interval"].as<int>();
10881091
if (!cli_explicit.count("dashboard_dir") && cfg["dashboard_dir"])
10891092
dashboard_dir = cfg["dashboard_dir"].as<std::string>();
1093+
if (cfg["analytics_id"])
1094+
analytics_id = cfg["analytics_id"].as<std::string>();
10901095
if (cfg["cache_max_shared_hashes"])
10911096
cache_max_shared_hashes = cfg["cache_max_shared_hashes"].as<int>();
10921097
if (cfg["cache_max_known_txs"])
@@ -1518,6 +1523,8 @@ int main(int argc, char* argv[]) {
15181523

15191524
// Dashboard serving directory and payout address for legacy API
15201525
web_server.set_dashboard_dir(dashboard_dir);
1526+
if (!analytics_id.empty())
1527+
web_server.set_analytics_id(analytics_id);
15211528
web_server.get_mining_interface()->set_payout_address(payout_address);
15221529
LOG_INFO << "Stratum config: min_diff=" << stratum_config.min_difficulty
15231530
<< " max_diff=" << stratum_config.max_difficulty

src/core/web_server.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,25 @@ void HttpSession::process_request()
469469
std::string contents((std::istreambuf_iterator<char>(file)),
470470
std::istreambuf_iterator<char>());
471471

472+
// Inject analytics tag into HTML pages if configured
473+
const auto& analytics_id = mining_interface_->get_analytics_id();
474+
if (!analytics_id.empty() && (ext == ".html" || ext == ".htm")) {
475+
auto pos = contents.find("</head>");
476+
if (pos == std::string::npos) pos = contents.find("</HEAD>");
477+
if (pos != std::string::npos) {
478+
std::string tag =
479+
"<!-- analytics -->\n"
480+
"<script async src=\"https://www.googletagmanager.com/gtag/js?id=" + analytics_id + "\"></script>\n"
481+
"<script>\n"
482+
"window.dataLayer=window.dataLayer||[];\n"
483+
"function gtag(){dataLayer.push(arguments);}\n"
484+
"gtag('js',new Date());\n"
485+
"gtag('config','" + analytics_id + "');\n"
486+
"</script>\n";
487+
contents.insert(pos, tag);
488+
}
489+
}
490+
472491
response.set(http::field::content_type, mime);
473492
response.set(http::field::cache_control, "public, max-age=3600");
474493
response.body() = std::move(contents);
@@ -5796,6 +5815,13 @@ void WebServer::set_dashboard_dir(const std::string& dir)
57965815
LOG_INFO << "Dashboard serving from: " << dir;
57975816
}
57985817

5818+
void WebServer::set_analytics_id(const std::string& id)
5819+
{
5820+
mining_interface_->set_analytics_id(id);
5821+
if (!id.empty())
5822+
LOG_INFO << "Analytics tag enabled: " << id;
5823+
}
5824+
57995825
bool WebServer::start_solo()
58005826
{
58015827
solo_mode_ = true;

src/core/web_server.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,10 @@ class MiningInterface : public jsonrpccxx::JsonRpc2Server
867867
void set_dashboard_dir(const std::string& dir) { m_dashboard_dir = dir; }
868868
const std::string& get_dashboard_dir() const { return m_dashboard_dir; }
869869

870+
// Google Analytics (or compatible) measurement ID injected into HTML pages
871+
void set_analytics_id(const std::string& id) { m_analytics_id = id; }
872+
const std::string& get_analytics_id() const { return m_analytics_id; }
873+
870874
// Primary payout address (for legacy /payout_addr endpoint)
871875
void set_payout_address(const std::string& addr) { m_payout_address = addr; }
872876
const std::string& get_payout_address() const { return m_payout_address; }
@@ -896,6 +900,8 @@ class MiningInterface : public jsonrpccxx::JsonRpc2Server
896900

897901
// Dashboard static file serving directory (empty = disabled)
898902
std::string m_dashboard_dir;
903+
// Google Analytics measurement ID (e.g. "G-XXXXXXXXXX")
904+
std::string m_analytics_id;
899905
// Primary payout address for legacy API
900906
std::string m_payout_address;
901907

@@ -1038,6 +1044,7 @@ class WebServer
10381044

10391045
// Dashboard directory for static file serving
10401046
void set_dashboard_dir(const std::string& dir);
1047+
void set_analytics_id(const std::string& id);
10411048

10421049
// Wire a live coin-daemon RPC connection for block template generation
10431050
void set_coin_rpc(ltc::coin::NodeRPC* rpc, ltc::interfaces::Node* coin = nullptr);

0 commit comments

Comments
 (0)