@@ -2,38 +2,65 @@ package main
22
33import (
44 "encoding/json"
5- "expvar"
65 "fmt"
76 "log/slog"
87 "net/http"
98
10- "tailscale .com/metrics "
9+ "github .com/prometheus/client_golang/prometheus "
1110 "xeiaso.net/v4/internal/github"
12- "xeiaso.net/v4/internal/lume"
1311)
1412
1513var (
16- sponsorsWebhookCount = metrics.LabelMap {Label : "action" }
17- sponsorsErrorCount = metrics.LabelMap {Label : "error_type" }
14+ sponsorsWebhookCount = prometheus .NewCounterVec (
15+ prometheus.CounterOpts {
16+ Name : "github_sponsors_webhook_total" ,
17+ Help : "Total number of GitHub Sponsors webhook events processed, by action" ,
18+ },
19+ []string {"action" },
20+ )
21+
22+ sponsorsErrorCount = prometheus .NewCounterVec (
23+ prometheus.CounterOpts {
24+ Name : "github_sponsors_webhook_errors_total" ,
25+ Help : "Total number of GitHub Sponsors webhook errors, by error type" ,
26+ },
27+ []string {"error_type" },
28+ )
1829)
1930
2031func init () {
21- expvar . Publish ( "gauge_xesite_sponsors_webhook_count" , & sponsorsWebhookCount )
22- expvar . Publish ( "gauge_xesite_sponsors_error_count" , & sponsorsErrorCount )
32+ prometheus . MustRegister ( sponsorsWebhookCount )
33+ prometheus . MustRegister ( sponsorsErrorCount )
2334}
2435
2536// GitHubSponsorsWebhook handles GitHub Sponsors webhook events.
2637type GitHubSponsorsWebhook struct {
27- fs * lume.FS
38+ // No lume.FS dependency for the standalone service
2839}
2940
3041// ServeHTTP processes incoming GitHub Sponsors webhook events.
3142func (gsh * GitHubSponsorsWebhook ) ServeHTTP (w http.ResponseWriter , r * http.Request ) {
43+ // Set CORS headers for web requests
44+ w .Header ().Set ("Access-Control-Allow-Origin" , "*" )
45+ w .Header ().Set ("Access-Control-Allow-Methods" , "POST, OPTIONS" )
46+ w .Header ().Set ("Access-Control-Allow-Headers" , "Content-Type, X-GitHub-Event, X-Hub-Signature-256" )
47+
48+ if r .Method == "OPTIONS" {
49+ w .WriteHeader (http .StatusOK )
50+ return
51+ }
52+
53+ if r .Method != "POST" {
54+ slog .Info ("method not allowed" , "method" , r .Method )
55+ http .Error (w , "Method not allowed" , http .StatusMethodNotAllowed )
56+ return
57+ }
58+
3259 // Check for GitHub Sponsors event header
3360 eventType := r .Header .Get ("X-GitHub-Event" )
3461 if eventType != "sponsorship" {
3562 slog .Info ("not a sponsorship event" , "event" , eventType )
36- sponsorsErrorCount .Add ("invalid_event_type" , 1 )
63+ sponsorsErrorCount .WithLabelValues ("invalid_event_type" ). Inc ( )
3764 http .Error (w , "Invalid event type" , http .StatusBadRequest )
3865 return
3966 }
@@ -42,13 +69,13 @@ func (gsh *GitHubSponsorsWebhook) ServeHTTP(w http.ResponseWriter, r *http.Reque
4269 var event github.SponsorsEvent
4370 if err := json .NewDecoder (r .Body ).Decode (& event ); err != nil {
4471 slog .Error ("error decoding GitHub Sponsors event" , "error" , err )
45- sponsorsErrorCount .Add ("decode_error" , 1 )
72+ sponsorsErrorCount .WithLabelValues ("decode_error" ). Inc ( )
4673 http .Error (w , err .Error (), http .StatusBadRequest )
4774 return
4875 }
4976
5077 // Increment the specific action counter
51- sponsorsWebhookCount .Add (event .Action , 1 )
78+ sponsorsWebhookCount .WithLabelValues (event .Action ). Inc ( )
5279
5380 // Log the sponsorship event
5481 slog .Info ("GitHub Sponsors webhook received" ,
@@ -57,6 +84,7 @@ func (gsh *GitHubSponsorsWebhook) ServeHTTP(w http.ResponseWriter, r *http.Reque
5784 "sponsorable" , event .Sponsorship .Sponsorable .Login ,
5885 "tier" , event .Sponsorship .Tier .Name ,
5986 "monthly_price" , event .Sponsorship .Tier .MonthlyPriceInDollars ,
87+ "sender" , event .Sender .Login ,
6088 )
6189
6290 // Handle different sponsorship event types
@@ -73,19 +101,22 @@ func (gsh *GitHubSponsorsWebhook) ServeHTTP(w http.ResponseWriter, r *http.Reque
73101 gsh .handlePendingCancellation (event )
74102 default :
75103 slog .Info ("unhandled GitHub Sponsors event type" , "action" , event .Action )
76- sponsorsErrorCount .Add ("unhandled_action" , 1 )
104+ sponsorsErrorCount .WithLabelValues ("unhandled_action" ). Inc ( )
77105 }
78106
79107 // Respond with success
108+ w .Header ().Set ("Content-Type" , "text/plain" )
80109 fmt .Fprintln (w , "OK" )
81110}
82111
83112// handleSponsorshipCreated processes new sponsorships
84113func (gsh * GitHubSponsorsWebhook ) handleSponsorshipCreated (event github.SponsorsEvent ) {
85114 slog .Info ("New sponsorship created" ,
86115 "sponsor" , event .Sponsorship .Sponsor .Login ,
116+ "sponsor_id" , event .Sponsorship .Sponsor .ID ,
87117 "tier" , event .Sponsorship .Tier .Name ,
88118 "monthly_price" , event .Sponsorship .Tier .MonthlyPriceInDollars ,
119+ "privacy_level" , event .Sponsorship .PrivacyLevel ,
89120 )
90121 // TODO: Add sponsorship creation logic here
91122 // This could include updating database records, sending notifications, etc.
@@ -95,8 +126,10 @@ func (gsh *GitHubSponsorsWebhook) handleSponsorshipCreated(event github.Sponsors
95126func (gsh * GitHubSponsorsWebhook ) handleSponsorshipEdited (event github.SponsorsEvent ) {
96127 slog .Info ("Sponsorship edited" ,
97128 "sponsor" , event .Sponsorship .Sponsor .Login ,
129+ "sponsor_id" , event .Sponsorship .Sponsor .ID ,
98130 "tier" , event .Sponsorship .Tier .Name ,
99131 "monthly_price" , event .Sponsorship .Tier .MonthlyPriceInDollars ,
132+ "privacy_level" , event .Sponsorship .PrivacyLevel ,
100133 )
101134 // TODO: Add sponsorship edit logic here
102135 // This could include updating records, changing access levels, etc.
@@ -106,6 +139,7 @@ func (gsh *GitHubSponsorsWebhook) handleSponsorshipEdited(event github.SponsorsE
106139func (gsh * GitHubSponsorsWebhook ) handleSponsorshipCancelled (event github.SponsorsEvent ) {
107140 slog .Info ("Sponsorship cancelled" ,
108141 "sponsor" , event .Sponsorship .Sponsor .Login ,
142+ "sponsor_id" , event .Sponsorship .Sponsor .ID ,
109143 "tier" , event .Sponsorship .Tier .Name ,
110144 )
111145 // TODO: Add sponsorship cancellation logic here
@@ -116,6 +150,7 @@ func (gsh *GitHubSponsorsWebhook) handleSponsorshipCancelled(event github.Sponso
116150func (gsh * GitHubSponsorsWebhook ) handlePendingTierChange (event github.SponsorsEvent ) {
117151 slog .Info ("Pending sponsorship tier change" ,
118152 "sponsor" , event .Sponsorship .Sponsor .Login ,
153+ "sponsor_id" , event .Sponsorship .Sponsor .ID ,
119154 "tier" , event .Sponsorship .Tier .Name ,
120155 "monthly_price" , event .Sponsorship .Tier .MonthlyPriceInDollars ,
121156 )
@@ -126,7 +161,8 @@ func (gsh *GitHubSponsorsWebhook) handlePendingTierChange(event github.SponsorsE
126161func (gsh * GitHubSponsorsWebhook ) handlePendingCancellation (event github.SponsorsEvent ) {
127162 slog .Info ("Pending sponsorship cancellation" ,
128163 "sponsor" , event .Sponsorship .Sponsor .Login ,
164+ "sponsor_id" , event .Sponsorship .Sponsor .ID ,
129165 "tier" , event .Sponsorship .Tier .Name ,
130166 )
131167 // TODO: Add pending cancellation logic here
132- }
168+ }
0 commit comments