package messages import ( "errors" "fmt" "github.com/android-sms-gateway/client-go/smsgateway" "github.com/android-sms-gateway/server/internal/sms-gateway/handlers/base" "github.com/android-sms-gateway/server/internal/sms-gateway/handlers/converters" "github.com/android-sms-gateway/server/internal/sms-gateway/handlers/middlewares/deviceauth" "github.com/android-sms-gateway/server/internal/sms-gateway/models" "github.com/android-sms-gateway/server/internal/sms-gateway/modules/messages" "github.com/capcom6/go-helpers/slices" "github.com/go-playground/validator/v10" "github.com/gofiber/fiber/v2" "go.uber.org/fx" "go.uber.org/zap" ) type mobileControllerParams struct { fx.In MessagesSvc *messages.Service Validator *validator.Validate Logger *zap.Logger } type MobileController struct { base.Handler messagesSvc *messages.Service } // @Summary Get messages for sending // @Description Returns list of pending messages // @Security MobileToken // @Tags Device, Messages // @Accept json // @Produce json // @Param order query string false "Message processing order: lifo (default) or fifo" Enums(lifo,fifo) default(lifo) // @Success 200 {object} smsgateway.MobileGetMessagesResponse "List of pending messages" // @Failure 400 {object} smsgateway.ErrorResponse "Invalid request" // @Failure 500 {object} smsgateway.ErrorResponse "Internal server error" // @Router /mobile/v1/message [get] // // Get messages for sending func (h *MobileController) list(device models.Device, c *fiber.Ctx) error { // Get and validate order parameter params := mobileGetQueryParams{} if err := h.QueryParserValidator(c, ¶ms); err != nil { return err } msgs, err := h.messagesSvc.SelectPending(device.ID, params.OrderOrDefault()) if err != nil { return fmt.Errorf("can't get messages: %w", err) } return c.JSON( smsgateway.MobileGetMessagesResponse( slices.Map( msgs, converters.MessageToMobileDTO, ), ), ) } // @Summary Update message state // @Description Updates message state // @Security MobileToken // @Tags Device, Messages // @Accept json // @Produce json // @Param request body smsgateway.MobilePatchMessageRequest true "List of message state updates" // @Success 204 {object} nil "Successfully updated" // @Failure 400 {object} smsgateway.ErrorResponse "Invalid request" // @Failure 500 {object} smsgateway.ErrorResponse "Internal server error" // @Router /mobile/v1/message [patch] // // Update message state func (h *MobileController) patch(device models.Device, c *fiber.Ctx) error { req := smsgateway.MobilePatchMessageRequest{} if err := h.BodyParserValidator(c, &req); err != nil { return err } for _, v := range req { messageState := messages.MessageStateIn{ ID: v.ID, State: messages.ProcessingState(v.State), Recipients: v.Recipients, States: v.States, } err := h.messagesSvc.UpdateState(device.ID, messageState) if err != nil && !errors.Is(err, messages.ErrMessageNotFound) { h.Logger.Error("Can't update message status", zap.String("message_id", v.ID), zap.Error(err), ) } } return c.SendStatus(fiber.StatusNoContent) } func (h *MobileController) Register(router fiber.Router) { router.Get("", deviceauth.WithDevice(h.list)) router.Patch("", deviceauth.WithDevice(h.patch)) } func NewMobileController(params mobileControllerParams) *MobileController { return &MobileController{ Handler: base.Handler{ Logger: params.Logger.Named("messages"), Validator: params.Validator, }, messagesSvc: params.MessagesSvc, } }