Skip to content

Commit 75aa114

Browse files
committed
[init] add some modules
1 parent 7700a6c commit 75aa114

File tree

20 files changed

+492
-1
lines changed

20 files changed

+492
-1
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ go.work
4747
.LSOverride
4848

4949
# Icon must end with two \r
50-
Icon
50+
Icon
51+
5152

5253
# Thumbnails
5354
._*
@@ -121,3 +122,4 @@ $RECYCLE.BIN/
121122

122123
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
123124

125+
coverage.html

.golangci.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ linters:
208208
- "^golang.org/x/tools/go/analysis.Analyzer$"
209209
- "^google.golang.org/protobuf/.+Options$"
210210
- "^gopkg.in/yaml.v3.Node$"
211+
- "^github.com/gofiber/fiber/v2.Config$"
212+
- "^github.com/gofiber/contrib/fiberzap/v2.Config$"
213+
- "^go.uber.org/fx.Hook$"
211214

212215
funlen:
213216
# Checks the number of lines in a function.
@@ -376,6 +379,9 @@ linters:
376379
- noctx
377380
- wrapcheck
378381
path: _test\.go
382+
- linters:
383+
- gochecknoglobals
384+
path: module\.go
379385
paths:
380386
- third_party$
381387
- builtin$

config/config.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package config
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"os"
7+
8+
"github.com/joho/godotenv"
9+
"github.com/kelseyhightower/envconfig"
10+
)
11+
12+
func Load[T any](c *T) error {
13+
err := godotenv.Load()
14+
if err != nil && !errors.Is(err, os.ErrNotExist) {
15+
return fmt.Errorf("failed to load .env file: %w", err)
16+
}
17+
18+
return loadFromEnv(c)
19+
}
20+
21+
func loadFromEnv[T any](c *T) error {
22+
if err := envconfig.Process("", c); err != nil {
23+
return fmt.Errorf("failed to load envconfig: %w", err)
24+
}
25+
26+
return nil
27+
}

go.mod

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
11
module github.com/android-sms-gateway/core
22

33
go 1.24.1
4+
5+
require (
6+
github.com/go-playground/validator/v10 v10.26.0
7+
github.com/gofiber/contrib/fiberzap/v2 v2.1.6
8+
github.com/gofiber/fiber/v2 v2.52.8
9+
github.com/joho/godotenv v1.5.1
10+
github.com/kelseyhightower/envconfig v1.4.0
11+
github.com/redis/go-redis/v9 v9.9.0
12+
go.uber.org/fx v1.24.0
13+
go.uber.org/zap v1.27.0
14+
)
15+
16+
require (
17+
github.com/andybalholm/brotli v1.1.0 // indirect
18+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
19+
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
20+
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
21+
github.com/go-playground/locales v0.14.1 // indirect
22+
github.com/go-playground/universal-translator v0.18.1 // indirect
23+
github.com/google/uuid v1.6.0 // indirect
24+
github.com/klauspost/compress v1.17.9 // indirect
25+
github.com/leodido/go-urn v1.4.0 // indirect
26+
github.com/mattn/go-colorable v0.1.13 // indirect
27+
github.com/mattn/go-isatty v0.0.20 // indirect
28+
github.com/mattn/go-runewidth v0.0.16 // indirect
29+
github.com/rivo/uniseg v0.2.0 // indirect
30+
github.com/valyala/bytebufferpool v1.0.0 // indirect
31+
github.com/valyala/fasthttp v1.56.0 // indirect
32+
github.com/valyala/tcplisten v1.0.0 // indirect
33+
go.uber.org/dig v1.19.0 // indirect
34+
go.uber.org/multierr v1.10.0 // indirect
35+
golang.org/x/crypto v0.33.0 // indirect
36+
golang.org/x/net v0.34.0 // indirect
37+
golang.org/x/sys v0.32.0 // indirect
38+
golang.org/x/text v0.22.0 // indirect
39+
)

go.sum

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
2+
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
3+
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
4+
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
5+
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
6+
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
7+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
8+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
9+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
10+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11+
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
12+
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
13+
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
14+
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
15+
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
16+
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
17+
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
18+
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
19+
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
20+
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
21+
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
22+
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
23+
github.com/gofiber/contrib/fiberzap/v2 v2.1.6 h1:8aMBaO7jAB4w9o2uGC1S3ieKPxg8vfJ7t1aipq2pudg=
24+
github.com/gofiber/contrib/fiberzap/v2 v2.1.6/go.mod h1:sGrPV2XzRrI6aJQOmORr5rdk4vXLR630Oc/REtMmCYs=
25+
github.com/gofiber/fiber/v2 v2.52.8 h1:xl4jJQ0BV5EJTA2aWiKw/VddRpHrKeZLF0QPUxqn0x4=
26+
github.com/gofiber/fiber/v2 v2.52.8/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
27+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
28+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
29+
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
30+
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
31+
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
32+
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
33+
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
34+
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
35+
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
36+
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
37+
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
38+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
39+
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
40+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
41+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
42+
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
43+
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
44+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
45+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
46+
github.com/redis/go-redis/v9 v9.9.0 h1:URbPQ4xVQSQhZ27WMQVmZSo3uT3pL+4IdHVcYq2nVfM=
47+
github.com/redis/go-redis/v9 v9.9.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
48+
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
49+
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
50+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
51+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
52+
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
53+
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
54+
github.com/valyala/fasthttp v1.56.0 h1:bEZdJev/6LCBlpdORfrLu/WOZXXxvrUQSiyniuaoW8U=
55+
github.com/valyala/fasthttp v1.56.0/go.mod h1:sReBt3XZVnudxuLOx4J/fMrJVorWRiWY2koQKgABiVI=
56+
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
57+
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
58+
go.uber.org/dig v1.19.0 h1:BACLhebsYdpQ7IROQ1AGPjrXcP5dF80U3gKoFzbaq/4=
59+
go.uber.org/dig v1.19.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
60+
go.uber.org/fx v1.24.0 h1:wE8mruvpg2kiiL1Vqd0CC+tr0/24XIB10Iwp2lLWzkg=
61+
go.uber.org/fx v1.24.0/go.mod h1:AmDeGyS+ZARGKM4tlH4FY2Jr63VjbEDJHtqXTGP5hbo=
62+
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
63+
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
64+
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
65+
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
66+
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
67+
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
68+
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
69+
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
70+
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
71+
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
72+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
73+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
74+
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
75+
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
76+
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
77+
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
78+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
79+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

handler/handler.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package handler
2+
3+
import (
4+
"github.com/android-sms-gateway/core/validator"
5+
"github.com/gofiber/fiber/v2"
6+
"go.uber.org/zap"
7+
)
8+
9+
type Base struct {
10+
Validator *validator.Validate
11+
Logger *zap.Logger
12+
}
13+
14+
func (c *Base) BodyParserValidator(ctx *fiber.Ctx, out interface{}) error {
15+
if err := ctx.BodyParser(out); err != nil {
16+
c.Logger.Error("failed to parse request", zap.Error(err))
17+
return fiber.NewError(fiber.StatusBadRequest, "failed to parse request")
18+
}
19+
20+
if err := c.Validator.Struct(out); err != nil {
21+
c.Logger.Error("failed to validate request", zap.Error(err))
22+
return fiber.NewError(fiber.StatusBadRequest, "failed to validate request")
23+
}
24+
25+
if v, ok := out.(validator.Validatable); ok {
26+
if err := v.Validate(); err != nil {
27+
c.Logger.Error("failed to validate request", zap.Error(err))
28+
return fiber.NewError(fiber.StatusBadRequest, "failed to validate request")
29+
}
30+
}
31+
32+
return nil
33+
}

http/config.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package http
2+
3+
import "github.com/gofiber/fiber/v2"
4+
5+
type Config struct {
6+
Address string
7+
ProxyHeader string
8+
Proxies []string
9+
}
10+
11+
type Options struct {
12+
getOnly bool
13+
views fiber.Views
14+
errorHandler fiber.ErrorHandler
15+
}
16+
17+
func (o *Options) WithGetOnly() *Options {
18+
o.getOnly = true
19+
return o
20+
}
21+
22+
func (o *Options) WithViews(views fiber.Views) *Options {
23+
o.views = views
24+
return o
25+
}
26+
27+
func (o *Options) WithErrorHandler(handler fiber.ErrorHandler) *Options {
28+
o.errorHandler = handler
29+
return o
30+
}

http/dto.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package http
2+
3+
type Error struct {
4+
Message string `json:"message"`
5+
Code int `json:"code,omitempty"`
6+
Details any `json:"details,omitempty"`
7+
}
8+
9+
type ErrorResponse struct {
10+
Error Error `json:"error"`
11+
}
12+
13+
func NewErrorResponse(message string, code int, details any) ErrorResponse {
14+
return ErrorResponse{
15+
Error: Error{
16+
Message: message,
17+
Code: code,
18+
Details: details,
19+
},
20+
}
21+
}

http/errors.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package http
2+
3+
import (
4+
"errors"
5+
6+
"github.com/gofiber/fiber/v2"
7+
"go.uber.org/zap"
8+
)
9+
10+
func preHandleError(err error, logger *zap.Logger) int {
11+
code := fiber.StatusInternalServerError
12+
13+
var e *fiber.Error
14+
if errors.As(err, &e) {
15+
code = e.Code
16+
}
17+
18+
if code >= fiber.StatusInternalServerError {
19+
logger.Error("An error occurred", zap.Error(err))
20+
}
21+
22+
return code
23+
}
24+
25+
func NewViewsErrorHandler(logger *zap.Logger, template string, layouts ...string) fiber.ErrorHandler {
26+
return func(c *fiber.Ctx, err error) error {
27+
code := preHandleError(err, logger)
28+
29+
return c.Status(code).Render(template, fiber.Map{"error": err.Error(), "code": code}, layouts...)
30+
}
31+
}
32+
33+
func NewJSONErrorHandler(logger *zap.Logger) fiber.ErrorHandler {
34+
return func(c *fiber.Ctx, err error) error {
35+
code := preHandleError(err, logger)
36+
37+
errorResponse := NewErrorResponse(err.Error(), code, nil)
38+
39+
return c.Status(code).JSON(errorResponse)
40+
}
41+
}

http/http.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package http
2+
3+
import (
4+
"github.com/gofiber/contrib/fiberzap/v2"
5+
"github.com/gofiber/fiber/v2"
6+
"github.com/gofiber/fiber/v2/middleware/recover"
7+
"go.uber.org/zap"
8+
)
9+
10+
func New(config Config, option Options, logger *zap.Logger) (*fiber.App, error) {
11+
app := fiber.New(fiber.Config{
12+
DisableStartupMessage: true,
13+
EnableIPValidation: true,
14+
EnableTrustedProxyCheck: true,
15+
ErrorHandler: option.errorHandler,
16+
GETOnly: option.getOnly,
17+
ProxyHeader: config.ProxyHeader,
18+
TrustedProxies: config.Proxies,
19+
Views: option.views,
20+
})
21+
app.Use(fiberzap.New(fiberzap.Config{
22+
SkipBody: func(c *fiber.Ctx) bool {
23+
return c.Response().StatusCode() < fiber.StatusBadRequest
24+
},
25+
Logger: logger,
26+
Fields: []string{"latency", "status", "method", "url", "ip", "ua", "body", "error"},
27+
}))
28+
app.Use(recover.New())
29+
30+
return app, nil
31+
}

0 commit comments

Comments
 (0)