Inital commit.

This commit is contained in:
Alfred Jophy 2026-02-05 18:25:40 +05:30
commit 0067db82b6
6 changed files with 1091 additions and 0 deletions

186
main.go Normal file
View file

@ -0,0 +1,186 @@
package main
import (
"bytes"
"encoding/json"
"fmt"
"html/template"
"log"
"net/mail"
"os"
"strings"
_ "leadsform/migrations"
altcha "github.com/altcha-org/altcha-lib-go"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/plugins/migratecmd"
"github.com/pocketbase/pocketbase/tools/mailer"
)
var altchaHMACKey = os.Getenv("ALTCHA_HMAC_KEY")
func mapToString(m map[string]string) string {
t, _ := template.New("body").Parse("Details \n\n{{.}}")
tr, _ := template.New("tr").Parse("{{.Key}} : {{.Value}} \n")
trString := ""
type TR struct {
Key string
Value string
}
for k, v := range m {
data := TR{
Key: k,
Value: v,
}
var buf bytes.Buffer
_ = tr.Execute(&buf, data)
trString = trString + buf.String()
}
var buf bytes.Buffer
_ = t.Execute(&buf, trString)
return buf.String()
}
func main() {
app := pocketbase.New()
app.OnServe().BindFunc(func(se *core.ServeEvent) error {
se.Router.GET("/altcha", func(e *core.RequestEvent) error {
orginH := e.Request.Header["Origin"]
if len(orginH) != 1 {
return e.Error(400, "Origin header is required", nil)
}
origin := orginH[0]
website, err := app.FindFirstRecordByData("websites", "url", origin)
if err != nil || website == nil {
return e.Error(400, "Invalid origin", nil)
}
challenge, err := altcha.CreateChallenge(altcha.ChallengeOptions{
HMACKey: altchaHMACKey,
MaxNumber: 50000,
})
if err != nil {
return e.Error(400, "Unable to create challenge", nil)
}
return e.JSON(200, challenge)
})
se.Router.POST("/lead", func(e *core.RequestEvent) error {
orginH := e.Request.Header["Origin"]
if len(orginH) != 1 {
return e.Error(400, "Origin header is required", nil)
}
origin := orginH[0]
website, err := app.FindFirstRecordByData("websites", "url", origin)
if err != nil {
return e.Error(400, "Invalid origin", nil)
}
info, err := e.RequestInfo()
if err != nil || info.Body == nil {
return e.Error(400, "Unable to parse request", err)
}
payload := info.Body["altcha"].(string)
if payload == "" {
return e.Error(400, "Altcha payload is required", nil)
}
formData := map[string][]string{}
for k, v := range info.Body {
formData[k] = []string{v.(string)}
}
fmt.Println(payload)
fmt.Println(altchaHMACKey)
verified, err := altcha.VerifySolution(payload, altchaHMACKey, true)
if err != nil || !verified {
return e.Error(400, "Invalid Altcha payload", nil)
}
collection, err := app.FindCollectionByNameOrId("leads")
if err != nil {
app.Logger().Error("Unable to find collection ~ leads", nil)
}
record := core.NewRecord(collection)
delete(info.Body, "altcha")
data, err := json.Marshal(info.Body)
if err != nil {
app.Logger().Warn("Unable to marshal data", nil)
return e.Error(400, "Unable to marshal data", nil)
}
record.Set("data", data)
record.Set("website", website.Id)
if err := app.Save(record); err != nil {
return e.Error(500, "Unable to save record", err)
}
return e.String(201, "Submitted")
})
return se.Next()
})
app.OnRecordAfterCreateSuccess("leads").BindFunc(func(e *core.RecordEvent) error {
go func() {
e.App.ExpandRecord(e.Record, []string{"website"}, nil)
website := e.Record.ExpandedOne("website")
subject := fmt.Sprintf("New lead from %s", website.GetString("url"))
data := make(map[string]string)
_ = json.Unmarshal([]byte(e.Record.GetString("data")), &data)
message := &mailer.Message{
From: mail.Address{
Address: e.App.Settings().Meta.SenderAddress,
Name: e.App.Settings().Meta.SenderName,
},
To: []mail.Address{{Address: website.GetString("notification_email")}},
Subject: subject,
Text: mapToString(data),
}
_ = e.App.NewMailClient().Send(message)
}()
return e.Next()
})
// loosely check if it was executed using "go run"
isGoRun := strings.HasPrefix(os.Args[0], os.TempDir())
migratecmd.MustRegister(app, app.RootCmd, migratecmd.Config{
// enable auto creation of migration files when making collection changes in the Dashboard
// (the isGoRun check is to enable it only during development)
Automigrate: isGoRun,
})
if err := app.Start(); err != nil {
log.Fatal(err)
}
}