Skip to content

Instantly share code, notes, and snippets.

@CerealKiller97
Created December 8, 2025 19:55
Show Gist options
  • Select an option

  • Save CerealKiller97/ffece8f256f60192cd1feac471268333 to your computer and use it in GitHub Desktop.

Select an option

Save CerealKiller97/ffece8f256f60192cd1feac471268333 to your computer and use it in GitHub Desktop.
RecaptchaService Go Implementation
package recaptcha
var ErrResponseEmpty = errors.New("response is an empty string")
const siteVerifyURL = "https://www.google.com/recaptcha/api/siteverify"
type (
V3Response struct {
ChallengeTS time.Time `json:"challenge_ts"`
Hostname string `json:"hostname"`
ErrorCodes []string `json:"error-codes"`
Success bool `json:"success"`
}
Interface interface {
Verify(ctx context.Context, response string, remoteIP string) (V3Response, error)
}
Service struct {
logger zerolog.Logger
client *http.Client
secret string
}
)
func New(secret string, logger zerolog.Logger) *Service {
return &Service{
logger: logger,
secret: secret,
client: &http.Client{},
}
}
var _ Interface = &Service{}
func (s Service) Verify(ctx context.Context, response string, remoteIP string) (V3Response, error) {
if response == "" {
return V3Response{}, ErrResponseEmpty
}
form := url.Values{
"secret": {s.secret},
"response": {response},
}
if len(remoteIP) > 0 {
form.Set("remoteip", remoteIP)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, siteVerifyURL, strings.NewReader(form.Encode()))
if err != nil {
return V3Response{}, fmt.Errorf("failed to create reCAPTCHA V3 request: %w", err)
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := s.client.Do(req) //nolint:bodyclose
if err != nil {
return V3Response{}, fmt.Errorf("failed to perform reCAPTCHA V3 request: %w", err)
}
defer func(Body io.ReadCloser) {
if err = Body.Close(); err != nil {
s.logger.Err(err).Msg("Error while closing response")
}
}(resp.Body)
var r V3Response
if err = json.NewDecoder(resp.Body).Decode(&r); err != nil {
return V3Response{}, err
}
return r, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment