Something went wrong. Try again.
Source code of my website codeka.io
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133package main
import ( "bytes" "context" "encoding/json" "flag" "fmt" "io" "net/http" "os" "time")
// APIRequest defines the body we send to Plausible.type APIRequest struct { SiteID string `json:"site_id"` Metrics []string `json:"metrics"` DateRange string `json:"date_range"` Dimensions []string `json:"dimensions"`}
// APIResult matches items under response.results// Example item: {"metrics": [270], "dimensions": ["/path/"]}type APIResult struct { Metrics []int64 `json:"metrics"` Dimensions []string `json:"dimensions"`}
// APIResponse is the top-level structure returned by Plausible.type APIResponse struct { Results []APIResult `json:"results"`}
// OutputEntry is the simplified shape we want to write: page/visits.type OutputEntry struct { Page string `json:"page"` Visits int64 `json:"visits"`}
func main() { var ( apiURL = flag.String("url", "https://plausible.io/api/v2/query", "Plausible API endpoint") siteID = flag.String("site", "dummy.site", "site_id parameter") date = flag.String("range", "7d", "date_range parameter (e.g., 7d, 30d, month") outFile = flag.String("out", "plausible-pages.json", "output JSON file path") ) flag.Parse()
apiKey := os.Getenv("PLAUSIBLE_API_KEY") if apiKey == "" { fmt.Fprintln(os.Stderr, "error: PLAUSIBLE_API_KEY environment variable is not set") os.Exit(1) }
reqBody := APIRequest{ SiteID: *siteID, Metrics: []string{ "pageviews", }, DateRange: *date, Dimensions: []string{ "event:page", }, } payload, err := json.Marshal(reqBody) if err != nil { fmt.Fprintf(os.Stderr, "marshal request: %v\n", err) os.Exit(1) }
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, *apiURL, bytes.NewReader(payload)) if err != nil { fmt.Fprintf(os.Stderr, "build request: %v\n", err) os.Exit(1) } req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 20 * time.Second} resp, err := client.Do(req) if err != nil { fmt.Fprintf(os.Stderr, "http request: %v\n", err) os.Exit(1) } defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 { b, _ := io.ReadAll(resp.Body) fmt.Fprintf(os.Stderr, "http error: %s\n%s\n", resp.Status, string(b)) os.Exit(1) }
var apiResp APIResponse if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil { fmt.Fprintf(os.Stderr, "decode response: %v\n", err) os.Exit(1) }
// Transform: results -> [{page, visits}] out := make([]OutputEntry, 0, len(apiResp.Results)) for _, r := range apiResp.Results { var page string if len(r.Dimensions) > 0 { page = r.Dimensions[0] } var visits int64 if len(r.Metrics) > 0 { visits = r.Metrics[0] } out = append(out, OutputEntry{Page: page, Visits: visits}) }
f, err := os.Create(*outFile) if err != nil { fmt.Fprintf(os.Stderr, "create output: %v\n", err) os.Exit(1) } defer f.Close()
enc := json.NewEncoder(f) enc.SetIndent("", " ") if err := enc.Encode(out); err != nil { fmt.Fprintf(os.Stderr, "write output: %v\n", err) os.Exit(1) }
fmt.Printf("wrote %d entries to %s\n", len(out), *outFile)}