# WebSMS OTP example - Go

Go 1.22+, std library only (`net/http`, `crypto/subtle`).

## Files
- `websms.go` - Client: token cache + auto-refresh, SendOTP, VerifyOTP
- `webhook.go` - `WebhookHandler` for `mo` (replies) + `dlr` (delivery reports)
- `demo.go` - end-to-end runnable demo (phone form -> SMS -> verify, with WebOTP autofill - body commented out, see notes)
- `main.go` - tiny demo wiring (commented out by default - see notes)
- `go.mod` - module file

## Quick start
```bash
go mod tidy
WEBSMS_CLIENT_ID=cid_... WEBSMS_CLIENT_SECRET=csk_... go run .
```

```go
import (
    "net/http"
    "time"

    websms "example.com/websms-otp"
)

c := websms.New(os.Getenv("WEBSMS_CLIENT_ID"), os.Getenv("WEBSMS_CLIENT_SECRET"))
if _, err := c.SendOTP("6421234567", "MyApp", "", "Valid for 5 minutes.", 5*time.Minute); err != nil {
    log.Fatal(err)
}

mux := http.NewServeMux()
mux.HandleFunc("/webhook", websms.WebhookHandler)
http.ListenAndServe(":3000", mux)
```

## Notes
- Files ship as `package websms` so the code can be vendored as a library.
  To run `main.go` standalone, change all three files to `package main` and
  uncomment the body of `main()`.
- Token + OTP storage is in-process and protected by a `sync.Mutex`. For
  multi-instance deployments swap the storage with Redis/DB.
- `VerifyOTP` is single-shot and caps at 5 attempts.
- Pass `code != ""` to `SendOTP` to control the value (4-8 digits, numeric).
