Skip to content

Commit fb65def

Browse files
committed
[mobile] refactor code by extracting controller
1 parent dfb21a5 commit fb65def

File tree

6 files changed

+189
-109
lines changed

6 files changed

+189
-109
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package messages
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
7+
"github.com/android-sms-gateway/client-go/smsgateway"
8+
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/base"
9+
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/converters"
10+
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/middlewares/deviceauth"
11+
"github.com/android-sms-gateway/server/internal/sms-gateway/models"
12+
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/messages"
13+
"github.com/capcom6/go-helpers/slices"
14+
"github.com/go-playground/validator/v10"
15+
"github.com/gofiber/fiber/v2"
16+
"go.uber.org/fx"
17+
"go.uber.org/zap"
18+
)
19+
20+
type mobileControllerParams struct {
21+
fx.In
22+
23+
MessagesSvc *messages.Service
24+
25+
Validator *validator.Validate
26+
Logger *zap.Logger
27+
}
28+
29+
type MobileController struct {
30+
base.Handler
31+
32+
messagesSvc *messages.Service
33+
}
34+
35+
// @Summary Get messages for sending
36+
// @Description Returns list of pending messages
37+
// @Security MobileToken
38+
// @Tags Device, Messages
39+
// @Accept json
40+
// @Produce json
41+
// @Param order query string false "Message processing order: lifo (default) or fifo" Enums(lifo,fifo)
42+
// @Success 200 {object} smsgateway.MobileGetMessagesResponse "List of pending messages"
43+
// @Failure 400 {object} smsgateway.ErrorResponse "Bad request"
44+
// @Failure 500 {object} smsgateway.ErrorResponse "Internal server error"
45+
// @Router /mobile/v1/message [get]
46+
//
47+
// Get messages for sending
48+
func (h *MobileController) list(device models.Device, c *fiber.Ctx) error {
49+
// Get and validate order parameter
50+
params := mobileGetQueryParams{}
51+
if err := h.QueryParserValidator(c, &params); err != nil {
52+
return fiber.NewError(fiber.StatusBadRequest, err.Error())
53+
}
54+
55+
msgs, err := h.messagesSvc.SelectPending(device.ID, messages.MessagesOrder(params.OrderOrDefault()))
56+
if err != nil {
57+
return fmt.Errorf("can't get messages: %w", err)
58+
}
59+
60+
return c.JSON(
61+
smsgateway.MobileGetMessagesResponse(
62+
slices.Map(
63+
msgs,
64+
converters.MessageToMobileDTO,
65+
),
66+
),
67+
)
68+
}
69+
70+
// @Summary Update message state
71+
// @Description Updates message state
72+
// @Security MobileToken
73+
// @Tags Device, Messages
74+
// @Accept json
75+
// @Produce json
76+
// @Param request body smsgateway.MobilePatchMessageRequest true "List of message state updates"
77+
// @Success 204 {object} nil "Successfully updated"
78+
// @Failure 400 {object} smsgateway.ErrorResponse "Invalid request"
79+
// @Failure 500 {object} smsgateway.ErrorResponse "Internal server error"
80+
// @Router /mobile/v1/message [patch]
81+
//
82+
// Update message state
83+
func (h *MobileController) patch(device models.Device, c *fiber.Ctx) error {
84+
var req smsgateway.MobilePatchMessageRequest
85+
if err := c.BodyParser(&req); err != nil {
86+
return fiber.NewError(fiber.StatusBadRequest, err.Error())
87+
}
88+
89+
for _, v := range req {
90+
messageState := messages.MessageStateIn{
91+
ID: v.ID,
92+
State: messages.ProcessingState(v.State),
93+
Recipients: v.Recipients,
94+
States: v.States,
95+
}
96+
97+
err := h.messagesSvc.UpdateState(device.ID, messageState)
98+
if err != nil && !errors.Is(err, messages.ErrMessageNotFound) {
99+
h.Logger.Error("Can't update message status", zap.Error(err))
100+
}
101+
}
102+
103+
return c.SendStatus(fiber.StatusNoContent)
104+
}
105+
106+
func (h *MobileController) Register(router fiber.Router) {
107+
router.Get("", deviceauth.WithDevice(h.list))
108+
router.Patch("", deviceauth.WithDevice(h.patch))
109+
}
110+
111+
func NewMobileController(params mobileControllerParams) *MobileController {
112+
return &MobileController{
113+
Handler: base.Handler{
114+
Logger: params.Logger.Named("messages"),
115+
Validator: params.Validator,
116+
},
117+
messagesSvc: params.MessagesSvc,
118+
}
119+
}

internal/sms-gateway/handlers/messages/params.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,15 @@ func (p *thirdPartyGetQueryParams) ToOptions() messages.MessagesSelectOptions {
7373

7474
return options
7575
}
76+
77+
type mobileGetQueryParams struct {
78+
Order string `query:"order" validate:"omitempty,oneof=lifo fifo"`
79+
}
80+
81+
func (p *mobileGetQueryParams) OrderOrDefault() string {
82+
if p.Order != "" {
83+
return p.Order
84+
}
85+
return "lifo"
86+
87+
}

internal/sms-gateway/handlers/mobile.go

Lines changed: 27 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
package handlers
22

33
import (
4-
"errors"
54
"fmt"
65
"strings"
76

87
"github.com/android-sms-gateway/client-go/smsgateway"
98
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/base"
109
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/converters"
1110
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/events"
11+
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/messages"
1212
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/middlewares/deviceauth"
1313
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/middlewares/userauth"
1414
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/settings"
1515
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/webhooks"
1616
"github.com/android-sms-gateway/server/internal/sms-gateway/models"
1717
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/auth"
1818
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/devices"
19-
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/messages"
2019
"github.com/capcom6/go-helpers/anys"
21-
"github.com/capcom6/go-helpers/slices"
2220
"github.com/go-playground/validator/v10"
2321
"github.com/gofiber/fiber/v2"
2422
"github.com/gofiber/fiber/v2/middleware/keyauth"
@@ -27,13 +25,28 @@ import (
2725
"go.uber.org/zap"
2826
)
2927

28+
type mobileHandlerParams struct {
29+
fx.In
30+
31+
Logger *zap.Logger
32+
Validator *validator.Validate
33+
34+
AuthSvc *auth.Service
35+
DevicesSvc *devices.Service
36+
37+
MessagesCtrl *messages.MobileController
38+
WebhooksCtrl *webhooks.MobileController
39+
SettingsCtrl *settings.MobileController
40+
EventsCtrl *events.MobileController
41+
}
42+
3043
type mobileHandler struct {
3144
base.Handler
3245

33-
authSvc *auth.Service
34-
devicesSvc *devices.Service
35-
messagesSvc *messages.Service
46+
authSvc *auth.Service
47+
devicesSvc *devices.Service
3648

49+
messagesCtrl *messages.MobileController
3750
webhooksCtrl *webhooks.MobileController
3851
settingsCtrl *settings.MobileController
3952
eventsCtrl *events.MobileController
@@ -151,87 +164,6 @@ func (h *mobileHandler) patchDevice(device models.Device, c *fiber.Ctx) error {
151164
return c.SendStatus(fiber.StatusNoContent)
152165
}
153166

154-
// @Summary Get messages for sending
155-
// @Description Returns list of pending messages
156-
// @Security MobileToken
157-
// @Tags Device, Messages
158-
// @Accept json
159-
// @Produce json
160-
// @Param order query string false "Message processing order: lifo (default) or fifo" Enums(lifo,fifo)
161-
// @Success 200 {object} smsgateway.MobileGetMessagesResponse "List of pending messages"
162-
// @Failure 400 {object} smsgateway.ErrorResponse "Bad request"
163-
// @Failure 500 {object} smsgateway.ErrorResponse "Internal server error"
164-
// @Router /mobile/v1/message [get]
165-
//
166-
// Get messages for sending
167-
func (h *mobileHandler) getMessage(device models.Device, c *fiber.Ctx) error {
168-
// Get and validate order parameter
169-
orderParam := c.Query("order")
170-
order := "lifo" // Default to LIFO
171-
172-
if orderParam != "" {
173-
orderParam = strings.ToLower(orderParam)
174-
switch orderParam {
175-
case "lifo":
176-
order = "lifo"
177-
case "fifo":
178-
order = "fifo"
179-
default:
180-
return fiber.NewError(fiber.StatusBadRequest, "Invalid order parameter. Must be 'lifo' or 'fifo'")
181-
}
182-
}
183-
184-
msgs, err := h.messagesSvc.SelectPending(device.ID, messages.MessagesOrder(order))
185-
if err != nil {
186-
return fmt.Errorf("can't get messages: %w", err)
187-
}
188-
189-
return c.JSON(
190-
smsgateway.MobileGetMessagesResponse(
191-
slices.Map(
192-
msgs,
193-
converters.MessageToMobileDTO,
194-
),
195-
),
196-
)
197-
}
198-
199-
// @Summary Update message state
200-
// @Description Updates message state
201-
// @Security MobileToken
202-
// @Tags Device, Messages
203-
// @Accept json
204-
// @Produce json
205-
// @Param request body smsgateway.MobilePatchMessageRequest true "List of message state updates"
206-
// @Success 204 {object} nil "Successfully updated"
207-
// @Failure 400 {object} smsgateway.ErrorResponse "Invalid request"
208-
// @Failure 500 {object} smsgateway.ErrorResponse "Internal server error"
209-
// @Router /mobile/v1/message [patch]
210-
//
211-
// Update message state
212-
func (h *mobileHandler) patchMessage(device models.Device, c *fiber.Ctx) error {
213-
var req smsgateway.MobilePatchMessageRequest
214-
if err := c.BodyParser(&req); err != nil {
215-
return fiber.NewError(fiber.StatusBadRequest, err.Error())
216-
}
217-
218-
for _, v := range req {
219-
messageState := messages.MessageStateIn{
220-
ID: v.ID,
221-
State: messages.ProcessingState(v.State),
222-
Recipients: v.Recipients,
223-
States: v.States,
224-
}
225-
226-
err := h.messagesSvc.UpdateState(device.ID, messageState)
227-
if err != nil && !errors.Is(err, messages.ErrMessageNotFound) {
228-
h.Logger.Error("Can't update message status", zap.Error(err))
229-
}
230-
}
231-
232-
return c.SendStatus(fiber.StatusNoContent)
233-
}
234-
235167
// @Summary Get one-time code for device registration
236168
// @Description Returns one-time code for device registration
237169
// @Security ApiAuth
@@ -321,43 +253,29 @@ func (h *mobileHandler) Register(router fiber.Router) {
321253

322254
router.Patch("/device", deviceauth.WithDevice(h.patchDevice))
323255

324-
router.Get("/message", deviceauth.WithDevice(h.getMessage))
325-
router.Patch("/message", deviceauth.WithDevice(h.patchMessage))
326-
327256
// Should be under `userauth.NewBasic` protection instead of `deviceauth`
328257
router.Patch("/user/password", deviceauth.WithDevice(h.changePassword))
329258

259+
h.messagesCtrl.Register(router.Group("/message"))
260+
h.messagesCtrl.Register(router.Group("/messages"))
330261
h.webhooksCtrl.Register(router.Group("/webhooks"))
331262
h.settingsCtrl.Register(router.Group("/settings"))
332263
h.eventsCtrl.Register(router.Group("/events"))
333264
}
334265

335-
type mobileHandlerParams struct {
336-
fx.In
337-
338-
Logger *zap.Logger
339-
Validator *validator.Validate
340-
341-
AuthSvc *auth.Service
342-
DevicesSvc *devices.Service
343-
MessagesSvc *messages.Service
344-
345-
WebhooksCtrl *webhooks.MobileController
346-
SettingsCtrl *settings.MobileController
347-
EventsCtrl *events.MobileController
348-
}
349-
350266
func newMobileHandler(params mobileHandlerParams) *mobileHandler {
351267
idGen, _ := nanoid.Standard(21)
352268

353269
return &mobileHandler{
354-
Handler: base.Handler{Logger: params.Logger, Validator: params.Validator},
355-
authSvc: params.AuthSvc,
270+
Handler: base.Handler{Logger: params.Logger, Validator: params.Validator},
271+
authSvc: params.AuthSvc,
272+
273+
messagesCtrl: params.MessagesCtrl,
356274
devicesSvc: params.DevicesSvc,
357-
messagesSvc: params.MessagesSvc,
358275
webhooksCtrl: params.WebhooksCtrl,
359276
settingsCtrl: params.SettingsCtrl,
360277
eventsCtrl: params.EventsCtrl,
361-
idGen: idGen,
278+
279+
idGen: idGen,
362280
}
363281
}

internal/sms-gateway/handlers/module.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ var Module = fx.Module(
2626
fx.Provide(
2727
newHealthHandler,
2828
messages.NewThirdPartyController,
29+
messages.NewMobileController,
2930
webhooks.NewThirdPartyController,
3031
webhooks.NewMobileController,
3132
devices.NewThirdPartyController,

pkg/swagger/docs/swagger.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,18 @@
982982
"Messages"
983983
],
984984
"summary": "Get messages for sending",
985+
"parameters": [
986+
{
987+
"enum": [
988+
"lifo",
989+
"fifo"
990+
],
991+
"type": "string",
992+
"description": "Message processing order: lifo (default) or fifo",
993+
"name": "order",
994+
"in": "query"
995+
}
996+
],
985997
"responses": {
986998
"200": {
987999
"description": "List of pending messages",
@@ -992,6 +1004,12 @@
9921004
}
9931005
}
9941006
},
1007+
"400": {
1008+
"description": "Bad request",
1009+
"schema": {
1010+
"$ref": "#/definitions/smsgateway.ErrorResponse"
1011+
}
1012+
},
9951013
"500": {
9961014
"description": "Internal server error",
9971015
"schema": {

pkg/swagger/docs/swagger.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,14 @@ paths:
14171417
consumes:
14181418
- application/json
14191419
description: Returns list of pending messages
1420+
parameters:
1421+
- description: 'Message processing order: lifo (default) or fifo'
1422+
enum:
1423+
- lifo
1424+
- fifo
1425+
in: query
1426+
name: order
1427+
type: string
14201428
produces:
14211429
- application/json
14221430
responses:
@@ -1426,6 +1434,10 @@ paths:
14261434
items:
14271435
$ref: '#/definitions/smsgateway.MobileMessage'
14281436
type: array
1437+
"400":
1438+
description: Bad request
1439+
schema:
1440+
$ref: '#/definitions/smsgateway.ErrorResponse'
14291441
"500":
14301442
description: Internal server error
14311443
schema:

0 commit comments

Comments
 (0)