commit 1f1e7fc6b7afff3bee234f2da187c909a8a04f0a Author: Arnaud Delcasse Date: Fri May 23 09:46:31 2025 +0200 initial commit diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..97da109 --- /dev/null +++ b/go.mod @@ -0,0 +1,21 @@ +module git.coopgo.io/coopgo-platform/sms + +go 1.23.3 + +require ( + github.com/fsnotify/fsnotify v1.8.0 // indirect + github.com/go-viper/mapstructure/v2 v2.2.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/sagikazarmark/locafero v0.7.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.12.0 // indirect + github.com/spf13/cast v1.7.1 // indirect + github.com/spf13/pflag v1.0.6 // indirect + github.com/spf13/viper v1.20.1 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.21.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..51edcb7 --- /dev/null +++ b/go.sum @@ -0,0 +1,36 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= +github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= +github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= +github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= +github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/providers/provider.go b/providers/provider.go new file mode 100644 index 0000000..e67c1af --- /dev/null +++ b/providers/provider.go @@ -0,0 +1,19 @@ +package providers + +import ( + "fmt" + + "github.com/spf13/viper" +) + +type SMSProvider interface { + Send(phoneNumber string, message string, sender string) error +} + +func NewSMSProvider(cfg *viper.Viper) (SMSProvider, error) { + provider := cfg.GetString("provider") + if provider == "smsfactor" { + return NewSMSFactorProvider(cfg.GetString("smsfactor.token")), nil + } + return nil, fmt.Errorf("provider %s not supported", provider) +} diff --git a/providers/smsfactor.go b/providers/smsfactor.go new file mode 100644 index 0000000..8a227fa --- /dev/null +++ b/providers/smsfactor.go @@ -0,0 +1,56 @@ +package providers + +import ( + "encoding/json" + "fmt" + "net/http" +) + +const SMSFACTOR_API = "https://api.smsfactor.com" + +type SMSFactorProvider struct { + Token string +} + +func NewSMSFactorProvider(token string) *SMSFactorProvider { + return &SMSFactorProvider{ + Token: token, + } +} + +func (p *SMSFactorProvider) Send(phoneNumber string, message string, sender string) error { + req, err := http.NewRequest("GET", SMSFACTOR_API+"/send", nil) + fmt.Println(p.Token) + req.Header.Add("Authorization", "Bearer "+p.Token) + req.Header.Add("Accept", "application/json") + + q := req.URL.Query() + q.Add("to", phoneNumber) + q.Add("text", message) + q.Add("sender", sender) + req.URL.RawQuery = q.Encode() + + fmt.Println(req.URL) + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return err + } + + var response map[string]any + err = json.NewDecoder(resp.Body).Decode(&response) + if err != nil { + return err + } + + if status, ok := response["status"].(float64); ok { + if status != 1 { + return fmt.Errorf("error sending sms : %s - %s", response["message"], response["details"]) + } + } else { + return fmt.Errorf("invalid response : status %s", response["status"]) + } + + return nil +} diff --git a/render/render.go b/render/render.go new file mode 100644 index 0000000..ab1c1d3 --- /dev/null +++ b/render/render.go @@ -0,0 +1,13 @@ +package render + +type Renderer struct { + config *viper.Viper +} + +func NewRenderer(cfg *viper.Viper, templatesDir string) &Renderer { + config: cfg, +} + +func (r *Renderer) GenerateMessage(template string, vars map[string]any) (*string, error) { + return nil, nil +} diff --git a/sms.go b/sms.go new file mode 100644 index 0000000..36428d1 --- /dev/null +++ b/sms.go @@ -0,0 +1,26 @@ +package sms + +import ( + "git.coopgo.io/coopgo-platform/sms/providers" + "github.com/spf13/viper" +) + +type SMSHandler struct { + Provider providers.SMSProvider + config *viper.Viper +} + +func NewSMSHandler(cfg *viper.Viper) (*SMSHandler, error) { + p, err := providers.NewSMSProvider(cfg) + if err != nil { + return nil, err + } + return &SMSHandler{ + Provider: p, + config: cfg, + }, nil +} + +func (h *SMSHandler) Send(phoneNumber string, message string, sender string) error { + return h.Provider.Send(phoneNumber, message, sender) +}