Go
Sign Ticketping identity tokens in Go with golang-jwt, as a net/http handler.
You’ll add one net/http handler that signs a token with golang-jwt. It works the same with chi, Echo, Gin or any router that accepts an http.HandlerFunc.
Install golang-jwt
go get github.com/golang-jwt/jwt/v5Set the secret
Get the identity secret from Settings → API → Identity secret and set it in your server’s environment. It’s the same value everywhere.
TICKETPING_IDENTITY_SECRET=tpis_...Add the handler
ticketping.go:
package main
import (
"net/http"
"os"
"time"
"github.com/golang-jwt/jwt/v5"
)
func ticketpingToken(w http.ResponseWriter, r *http.Request) {
user, ok := currentUser(r)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
claims := jwt.MapClaims{"sub": user.ID, "exp": time.Now().Add(5 * time.Minute).Unix()}
if user.Email != "" {
claims["email"] = user.Email
}
if user.Name != "" {
claims["name"] = user.Name
}
secret := []byte(os.Getenv("TICKETPING_IDENTITY_SECRET"))
token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secret)
if err != nil {
http.Error(w, "Unable to sign token", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(token))
}currentUser stands for your session lookup: it returns the signed-in user and whether there is one. user.ID must be a string; use strconv.FormatInt(id, 10) for numeric IDs.
Register it (Go 1.22 or later for method patterns):
http.HandleFunc("POST /api/ticketping-token", ticketpingToken)Empty Email and Name are left out, because Ticketping refuses empty or null claims. In production, read the secret once at startup and fail if it’s empty, rather than signing with an empty key.
Call it from the frontend
Ticketping('identify', {
userId: user.id,
email: user.email,
name: user.name,
getToken: async () => {
const res = await fetch('/api/ticketping-token', { method: 'POST', credentials: 'include' })
if (!res.ok) throw new Error(`Ticketping token request failed (${res.status})`)
return res.text()
}
})Add your CSRF header if you use CSRF middleware (such as gorilla/csrf or Go 1.25’s http.CrossOriginProtection, which needs nothing extra for same-origin fetch).
Check that it works
- Sign in on localhost and run
await (await fetch('/api/ticketping-token', { method: 'POST' })).text()in the browser console. - Paste the token into the token validator under Settings → API → Identity secret. It shows the claims, or says exactly what to fix.
- Reload and send a message. The dashboard shows it with the user’s name and a Verified badge.
Copy prompt for your AI coding agent
Add Ticketping identity verification (chat widget v2) to this Go server.
Docs index: https://ticketping.com/llms.txt
This page as Markdown: https://ticketping.com/docs/identity-go.md
1. go get github.com/golang-jwt/jwt/v5.
2. Add the ticketpingToken handler exactly as on the docs page, using this app's session lookup instead of currentUser:
401 when signed out, otherwise jwt.MapClaims{"sub": <user ID as string>, "exp": time.Now().Add(5 * time.Minute).Unix()}
plus email and name only when non-empty, signed with jwt.SigningMethodHS256 and
[]byte(os.Getenv("TICKETPING_IDENTITY_SECRET")), written as text/plain.
Register it for POST /api/ticketping-token on this app's router.
3. Add TICKETPING_IDENTITY_SECRET= to the env example file. Never commit the value.
4. In the frontend, call Ticketping('identify', { userId, email, name, getToken }) where getToken POSTs to the route
(with any CSRF header this app uses) and returns res.text().
5. Tell me how to verify with the token validator at Settings → API → Identity secret.