Skip to content

Commit

Permalink
add example
Browse files Browse the repository at this point in the history
  • Loading branch information
rokostik committed Jan 22, 2024
1 parent d12ae87 commit 1e57356
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 0 deletions.
23 changes: 23 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Friendly Captcha Go Example

This application integrates Friendly Captcha for form submissions using Go.

### Requirements

- Go
- Your Friendly Captcha API key and site key.

### Start the application

- Setup env variables and start the application

> NOTE: `FRC_SITEVERIFY_ENDPOINT` and `FRC_WIDGET_ENDPOINT` are optional. If not set, the default values will be used. You can also use `global` or `eu` as shorthands for both.
```bash
FRC_APIKEY=<your api key> FRC_SITEKEY=<your site key> FRC_SITEVERIFY_ENDPINT=<siteverify endpoint> FRC_WIDGET_ENDPOINT=<widget endpoint> go run main.go
```

# Usage

Navigate to http://localhost:3000/ in your browser.
Fill out the form and submit. The Friendly Captcha verification will protect the form from bots.
83 changes: 83 additions & 0 deletions example/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Friendly Captcha Python SDK example</title>
<style>
* {
box-sizing: border-box;
}

body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
width: 100vw;
background-color: #f2f2f2;
}

h1 {
font-size: 1.4em;
}

main {
width: 100%;
max-width: 680px;
}

.message {
width: 100%;
padding: 0.5em 2em;
margin: 1.5em 0;
border-radius: 8px;
}

.message h2 {
margin-bottom: 0;
}

label {
display: block;
}
</style>

<script type="module" src="https://cdn.jsdelivr.net/npm/@friendlycaptcha/sdk/site.min.js" async defer></script>
<script nomodule src="https://cdn.jsdelivr.net/npm/@friendlycaptcha/sdk/site.compat.min.js" async defer></script>

<!-- You can change the data-api-endpoint via this tag. More info here https://developer.friendlycaptcha.com/docs/sdk/configuration -->
<!-- <meta name="frc-api-endpoint" content="."> -->
</head>

<body>
<main>
<h1>Friendly Captcha Go SDK form</h1>
{{if .Message}}
<p>{{.Message}}</p>
{{end}}
<form method="POST">
<div class="form-group">
<label>Subject:</label><br />
<input type="text" name="subject" /><br />
<label>Message:</label><br />
<textarea name="message"></textarea><br />

<div class="frc-captcha" data-sitekey="{{.Sitekey}}" {{if
.WidgetEndpoint}}data-api-endpoint="{{.WidgetEndpoint}}" {{end}}></div>
<input style="margin-top: 1em" type="submit" value="Submit" />
</div>
</form>
</main>
<script>
if (window.history.replaceState) {
window.history.replaceState(null, null, window.location.href);
}
</script>
</body>

</html>
8 changes: 8 additions & 0 deletions example/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/friendlycaptcha/friendly-captcha-go/example

// TODO replace when module is published
replace github.com/friendlycaptcha/friendly-captcha-go => ../

go 1.21.6

require github.com/friendlycaptcha/friendly-captcha-go v0.0.0-00010101000000-000000000000
8 changes: 8 additions & 0 deletions example/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
109 changes: 109 additions & 0 deletions example/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package main

import (
"html/template"
"log"
"net/http"
"os"

friendlycaptcha "github.com/friendlycaptcha/friendly-captcha-go"
)

type formMessage struct {
Subject string
Message string
}

type templateData struct {
Message string
Sitekey string
WidgetEndpoint string
}

func main() {
sitekey := os.Getenv("FRC_SITEKEY")
apikey := os.Getenv("FRC_APIKEY")

// Optionally we can pass in custom endpoints to be used, such as "eu".
siteverifyEndpoint := os.Getenv("FRC_SITEVERIFY_ENDPOINT")
widgetEndpoint := os.Getenv("FRC_WIDGET_ENDPOINT")

if sitekey == "" || apikey == "" {
log.Fatalf("Please set the FRC_SITEKEY and FRC_APIKEY environment values before running this example to your Friendly Captcha sitekey and apikey respectively.")
}

opts := []friendlycaptcha.ClientOption{
friendlycaptcha.WithAPIKey(apikey),
friendlycaptcha.WithSitekey(sitekey),
}
if siteverifyEndpoint != "" {
opts = append(opts, friendlycaptcha.WithSiteverifyEndpoint(siteverifyEndpoint)) // optional, defaults to "global"
}
frcClient := friendlycaptcha.NewClient(opts...)
tmpl := template.Must(template.ParseFiles("demo.html"))

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// GET - the user is requesting the form, not submitting it.
if r.Method != http.MethodPost {
err := tmpl.Execute(w, templateData{
Message: "",
Sitekey: sitekey,
WidgetEndpoint: widgetEndpoint,
})
if err != nil {
log.Fatal("erorr executing template: ", err)
}
return
}

form := formMessage{
Subject: r.FormValue("subject"),
Message: r.FormValue("message"),
}

solution := r.FormValue("frc-captcha-response")
result := frcClient.VerifyCaptchaResponse(r.Context(), solution)

if !result.WasAbleToVerify() {
// In this case we were not actually able to verify the response embedded in the form, but we may still want to accept it.
// It could mean there is a network issue or that the service is down. In those cases you generally want to accept submissions anyhow.
// That's why we use `shouldAccept()` below to actually accept or reject the form submission. It will return true in these cases.

if result.IsErrorDueToClientError() {
// Something is wrong with our configuration, check your API key!
// Send yourself an alert to fix this! Your site is unprotected until you fix this.
log.Printf("CAPTCHA CONFIG ERROR: %s\n", result.RequestError())
} else {
log.Printf("Failed to verify captcha response: %s\n", result.RequestError())
}
}

if !result.ShouldAccept() {
err := tmpl.Execute(w, templateData{
Message: "❌ Anti-robot check failed, please try again.",
Sitekey: sitekey,
WidgetEndpoint: widgetEndpoint,
})
if err != nil {
log.Fatal("erorr executing template: ", err)
}
return
}

// The captcha was OK, process the form.
_ = form

err := tmpl.Execute(w, templateData{
Message: "✅ Your message has been submitted successfully.",
Sitekey: sitekey,
WidgetEndpoint: widgetEndpoint,
})
if err != nil {
log.Fatal("erorr executing template: ", err)
}
})
log.Printf("Starting server on localhost port 8844 (http://localhost:8844)")

//nolint:errcheck,gosec // this is an example
http.ListenAndServe(":8844", nil)
}

0 comments on commit 1e57356

Please sign in to comment.