mirror of
https://github.com/makayabou/asg-server.git
synced 2026-05-02 17:43:36 +02:00
[feature] add inbox export endpoint
This commit is contained in:
parent
35c3ad3718
commit
70297a5007
2
go.mod
2
go.mod
@ -4,7 +4,7 @@ go 1.22.0
|
||||
|
||||
require (
|
||||
firebase.google.com/go/v4 v4.12.1
|
||||
github.com/android-sms-gateway/client-go v1.2.0
|
||||
github.com/android-sms-gateway/client-go v1.2.1-0.20241231042455-ce468dd89fdb
|
||||
github.com/ansrivas/fiberprometheus/v2 v2.6.1
|
||||
github.com/capcom6/go-helpers v0.0.0-20240521035631-865ee2879fa3
|
||||
github.com/capcom6/go-infra-fx v0.2.0
|
||||
|
||||
4
go.sum
4
go.sum
@ -28,6 +28,10 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEV
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/android-sms-gateway/client-go v1.2.0 h1:P02e/Nm2XY6gpxVQVZiaxh1ZfInVkwfOLzz8Mp/1dy0=
|
||||
github.com/android-sms-gateway/client-go v1.2.0/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
|
||||
github.com/android-sms-gateway/client-go v1.2.1-0.20241231005427-53ab5bf34e4f h1:BfLaSqzXTRwAiXafZO/kA7kK8uPEXNB/32iHfSJlOSE=
|
||||
github.com/android-sms-gateway/client-go v1.2.1-0.20241231005427-53ab5bf34e4f/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
|
||||
github.com/android-sms-gateway/client-go v1.2.1-0.20241231042455-ce468dd89fdb h1:c3ll8h375G/oL4Qzexo35XBxHrw9HgGOqmxK6CPX5Bg=
|
||||
github.com/android-sms-gateway/client-go v1.2.1-0.20241231042455-ce468dd89fdb/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/ansrivas/fiberprometheus/v2 v2.6.1 h1:wac3pXaE6BYYTF04AC6K0ktk6vCD+MnDOJZ3SK66kXM=
|
||||
|
||||
@ -126,9 +126,47 @@ func (h *ThirdPartyController) get(user models.User, c *fiber.Ctx) error {
|
||||
return c.JSON(state)
|
||||
}
|
||||
|
||||
// @Summary Request inbox messages export
|
||||
// @Description Initiates process of inbox messages export via webhooks. For each message the `sms:received` webhook will be triggered. The webhooks will be triggered without specific order.
|
||||
// @Security ApiAuth
|
||||
// @Tags User, Messages
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body smsgateway.MessagesExportRequest true "Export inbox request"
|
||||
// @Success 202 {object} object "Inbox export request accepted"
|
||||
// @Failure 400 {object} smsgateway.ErrorResponse "Invalid request"
|
||||
// @Failure 401 {object} smsgateway.ErrorResponse "Unauthorized"
|
||||
// @Failure 500 {object} smsgateway.ErrorResponse "Internal server error"
|
||||
// @Router /3rdparty/v1/inbox/export [post]
|
||||
//
|
||||
// Export inbox
|
||||
func (h *ThirdPartyController) postInboxExport(user models.User, c *fiber.Ctx) error {
|
||||
req := smsgateway.MessagesExportRequest{}
|
||||
if err := h.BodyParserValidator(c, &req); err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
device, err := h.devicesSvc.Get(devices.WithUserID(user.ID), devices.WithID(req.DeviceID))
|
||||
if err != nil {
|
||||
if errors.Is(err, devices.ErrNotFound) {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid device ID")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if err := h.messagesSvc.ExportInbox(device, req.Since, req.Until); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.SendStatus(fiber.StatusAccepted)
|
||||
}
|
||||
|
||||
func (h *ThirdPartyController) Register(router fiber.Router) {
|
||||
router.Post("", auth.WithUser(h.post))
|
||||
router.Get(":id", auth.WithUser(h.get))
|
||||
|
||||
router.Post("inbox/export", auth.WithUser(h.postInboxExport))
|
||||
}
|
||||
|
||||
func NewThirdPartyController(params thirdPartyControllerParams) *ThirdPartyController {
|
||||
|
||||
@ -3,6 +3,7 @@ package messages
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
@ -244,6 +245,16 @@ func (s *Service) Enqeue(device models.Device, message smsgateway.Message, opts
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (s *Service) ExportInbox(device models.Device, since, until time.Time) error {
|
||||
if device.PushToken == nil {
|
||||
return errors.New("no push token")
|
||||
}
|
||||
|
||||
event := push.NewMessagesExportRequestedEvent(since, until)
|
||||
|
||||
return s.pushSvc.Enqueue(*device.PushToken, event)
|
||||
}
|
||||
|
||||
func (s *Service) Clean(ctx context.Context) error {
|
||||
//TODO: use delete queue to optimize deletion
|
||||
n, err := s.messages.removeProcessed(ctx, time.Now().Add(-s.config.ProcessedLifetime))
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/push/domain"
|
||||
"github.com/android-sms-gateway/server/pkg/types/cache"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
@ -36,7 +37,7 @@ type Service struct {
|
||||
|
||||
client client
|
||||
|
||||
cache *cache.Cache[Event]
|
||||
cache *cache.Cache[domain.Event]
|
||||
|
||||
enqueuedCounter *prometheus.CounterVec
|
||||
|
||||
@ -61,7 +62,7 @@ func New(params Params) *Service {
|
||||
return &Service{
|
||||
config: params.Config,
|
||||
client: params.Client,
|
||||
cache: cache.New[Event](cache.Config{}),
|
||||
cache: cache.New[domain.Event](cache.Config{}),
|
||||
enqueuedCounter: enqueuedCounter,
|
||||
logger: params.Logger,
|
||||
}
|
||||
@ -83,7 +84,7 @@ func (s *Service) Run(ctx context.Context) {
|
||||
}
|
||||
|
||||
// Enqueue adds the data to the cache and immediately sends all messages if the debounce is 0.
|
||||
func (s *Service) Enqueue(token string, event *Event) error {
|
||||
func (s *Service) Enqueue(token string, event *domain.Event) error {
|
||||
if err := s.cache.Set(token, *event); err != nil {
|
||||
return fmt.Errorf("can't add message to cache: %w", err)
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package push
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/android-sms-gateway/client-go/smsgateway"
|
||||
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/push/domain"
|
||||
@ -17,14 +18,24 @@ const (
|
||||
|
||||
type client interface {
|
||||
Open(ctx context.Context) error
|
||||
Send(ctx context.Context, messages map[string]Event) error
|
||||
Send(ctx context.Context, messages map[string]domain.Event) error
|
||||
Close(ctx context.Context) error
|
||||
}
|
||||
|
||||
func NewMessageEnqueuedEvent() *Event {
|
||||
func NewMessageEnqueuedEvent() *domain.Event {
|
||||
return domain.NewEvent(smsgateway.PushMessageEnqueued, nil)
|
||||
}
|
||||
|
||||
func NewWebhooksUpdatedEvent() *Event {
|
||||
func NewWebhooksUpdatedEvent() *domain.Event {
|
||||
return domain.NewEvent(smsgateway.PushWebhooksUpdated, nil)
|
||||
}
|
||||
|
||||
func NewMessagesExportRequestedEvent(since, until time.Time) *domain.Event {
|
||||
return domain.NewEvent(
|
||||
smsgateway.PushMessagesExportRequested,
|
||||
map[string]string{
|
||||
"since": since.Format(time.RFC3339),
|
||||
"until": until.Format(time.RFC3339),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ GET {{baseUrl}}/health HTTP/1.1
|
||||
GET {{baseUrl}}/api/3rdparty/v1/health HTTP/1.1
|
||||
|
||||
###
|
||||
POST {{baseUrl}}/api/3rdparty/v1/message?skipPhoneValidation=false HTTP/1.1
|
||||
POST {{baseUrl}}/api/3rdparty/v1/messages?skipPhoneValidation=false HTTP/1.1
|
||||
Content-Type: application/json
|
||||
Authorization: Basic {{credentials}}
|
||||
|
||||
@ -25,7 +25,7 @@ Authorization: Basic {{credentials}}
|
||||
}
|
||||
|
||||
###
|
||||
POST {{baseUrl}}/api/3rdparty/v1/message HTTP/1.1
|
||||
POST {{baseUrl}}/api/3rdparty/v1/messages HTTP/1.1
|
||||
Content-Type: application/json
|
||||
Authorization: Basic {{credentials}}
|
||||
|
||||
@ -41,9 +41,20 @@ Authorization: Basic {{credentials}}
|
||||
}
|
||||
|
||||
###
|
||||
GET {{baseUrl}}/api/3rdparty/v1/message/K56aIsVsQ2rECdv_ajzTd HTTP/1.1
|
||||
GET {{baseUrl}}/api/3rdparty/v1/messages/K56aIsVsQ2rECdv_ajzTd HTTP/1.1
|
||||
Authorization: Basic {{credentials}}
|
||||
|
||||
###
|
||||
POST {{baseUrl}}/api/3rdparty/v1/messages/inbox/export HTTP/1.1
|
||||
Authorization: Basic {{credentials}}
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"since": "2024-12-01T00:00:00.000Z",
|
||||
"until": "2024-12-31T23:59:59.999Z",
|
||||
"deviceId": "MxKw03Q2ZVoomrLeDLlMO"
|
||||
}
|
||||
|
||||
###
|
||||
GET {{baseUrl}}/api/3rdparty/v1/devices HTTP/1.1
|
||||
Authorization: Basic {{credentials}}
|
||||
|
||||
@ -86,6 +86,64 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/3rdparty/v1/inbox/export": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Initiates process of inbox messages export via webhooks. For each message the `sms:received` webhook will be triggered. The webhooks will be triggered without specific order.",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"User",
|
||||
"Messages"
|
||||
],
|
||||
"summary": "Request inbox messages export",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Export inbox request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smsgateway.MessagesExportRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"202": {
|
||||
"description": "Inbox export request accepted",
|
||||
"schema": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smsgateway.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smsgateway.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal server error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smsgateway.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/3rdparty/v1/logs": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -149,7 +207,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/3rdparty/v1/message": {
|
||||
"/3rdparty/v1/messages": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -225,7 +283,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/3rdparty/v1/message/{id}": {
|
||||
"/3rdparty/v1/messages/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
@ -1075,6 +1133,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"smsgateway.MessagesExportRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"deviceId",
|
||||
"since",
|
||||
"until"
|
||||
],
|
||||
"properties": {
|
||||
"deviceId": {
|
||||
"description": "DeviceID is the ID of the device to export messages for.",
|
||||
"type": "string",
|
||||
"maxLength": 21,
|
||||
"example": "PyDmBQZZXYmyxMwED8Fzy"
|
||||
},
|
||||
"since": {
|
||||
"description": "Since is the start of the time range to export.",
|
||||
"type": "string",
|
||||
"example": "2024-01-01T00:00:00Z"
|
||||
},
|
||||
"until": {
|
||||
"description": "Until is the end of the time range to export.",
|
||||
"type": "string",
|
||||
"example": "2024-01-01T23:59:59Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
"smsgateway.MobileChangePasswordRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -1198,11 +1282,13 @@
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"MessageEnqueued",
|
||||
"WebhooksUpdated"
|
||||
"WebhooksUpdated",
|
||||
"MessagesExportRequested"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"PushMessageEnqueued",
|
||||
"PushWebhooksUpdated"
|
||||
"PushWebhooksUpdated",
|
||||
"PushMessagesExportRequested"
|
||||
]
|
||||
},
|
||||
"smsgateway.PushNotification": {
|
||||
@ -1223,7 +1309,8 @@
|
||||
"default": "MessageEnqueued",
|
||||
"enum": [
|
||||
"MessageEnqueued",
|
||||
"WebhooksUpdated"
|
||||
"WebhooksUpdated",
|
||||
"MessagesExportRequested"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
|
||||
@ -211,6 +211,26 @@ definitions:
|
||||
- recipients
|
||||
- state
|
||||
type: object
|
||||
smsgateway.MessagesExportRequest:
|
||||
properties:
|
||||
deviceId:
|
||||
description: DeviceID is the ID of the device to export messages for.
|
||||
example: PyDmBQZZXYmyxMwED8Fzy
|
||||
maxLength: 21
|
||||
type: string
|
||||
since:
|
||||
description: Since is the start of the time range to export.
|
||||
example: "2024-01-01T00:00:00Z"
|
||||
type: string
|
||||
until:
|
||||
description: Until is the end of the time range to export.
|
||||
example: "2024-01-01T23:59:59Z"
|
||||
type: string
|
||||
required:
|
||||
- deviceId
|
||||
- since
|
||||
- until
|
||||
type: object
|
||||
smsgateway.MobileChangePasswordRequest:
|
||||
properties:
|
||||
currentPassword:
|
||||
@ -305,10 +325,12 @@ definitions:
|
||||
enum:
|
||||
- MessageEnqueued
|
||||
- WebhooksUpdated
|
||||
- MessagesExportRequested
|
||||
type: string
|
||||
x-enum-varnames:
|
||||
- PushMessageEnqueued
|
||||
- PushWebhooksUpdated
|
||||
- PushMessagesExportRequested
|
||||
smsgateway.PushNotification:
|
||||
properties:
|
||||
data:
|
||||
@ -324,6 +346,7 @@ definitions:
|
||||
enum:
|
||||
- MessageEnqueued
|
||||
- WebhooksUpdated
|
||||
- MessagesExportRequested
|
||||
example: MessageEnqueued
|
||||
token:
|
||||
description: The token of the device that receives the notification.
|
||||
@ -444,6 +467,45 @@ paths:
|
||||
summary: Health check
|
||||
tags:
|
||||
- System
|
||||
/3rdparty/v1/inbox/export:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Initiates process of inbox messages export via webhooks. For each
|
||||
message the `sms:received` webhook will be triggered. The webhooks will be
|
||||
triggered without specific order.
|
||||
parameters:
|
||||
- description: Export inbox request
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/smsgateway.MessagesExportRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"202":
|
||||
description: Inbox export request accepted
|
||||
schema:
|
||||
type: object
|
||||
"400":
|
||||
description: Invalid request
|
||||
schema:
|
||||
$ref: '#/definitions/smsgateway.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/smsgateway.ErrorResponse'
|
||||
"500":
|
||||
description: Internal server error
|
||||
schema:
|
||||
$ref: '#/definitions/smsgateway.ErrorResponse'
|
||||
security:
|
||||
- ApiAuth: []
|
||||
summary: Request inbox messages export
|
||||
tags:
|
||||
- User
|
||||
- Messages
|
||||
/3rdparty/v1/logs:
|
||||
get:
|
||||
description: Retrieve a list of log entries within a specified time range.
|
||||
@ -487,7 +549,7 @@ paths:
|
||||
tags:
|
||||
- System
|
||||
- Logs
|
||||
/3rdparty/v1/message:
|
||||
/3rdparty/v1/messages:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
@ -537,7 +599,7 @@ paths:
|
||||
tags:
|
||||
- User
|
||||
- Messages
|
||||
/3rdparty/v1/message/{id}:
|
||||
/3rdparty/v1/messages/{id}:
|
||||
get:
|
||||
description: Returns message state by ID
|
||||
parameters:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user