mirror of
https://github.com/makayabou/asg-server.git
synced 2026-05-02 17:43:36 +02:00
[deps] move client and shared structs to another repo
This commit is contained in:
parent
1a8b275484
commit
0213382a19
1
go.mod
1
go.mod
@ -4,6 +4,7 @@ go 1.22.0
|
||||
|
||||
require (
|
||||
firebase.google.com/go/v4 v4.12.1
|
||||
github.com/android-sms-gateway/client-go v1.0.0
|
||||
github.com/capcom6/go-helpers v0.0.0-20240521035030-5f57bddeecee
|
||||
github.com/capcom6/go-infra-fx v0.0.2
|
||||
github.com/go-playground/validator/v10 v10.16.0
|
||||
|
||||
4
go.sum
4
go.sum
@ -28,6 +28,10 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/android-sms-gateway/client-go v0.0.0-20240530135354-8d1ce85b9734 h1:dwNjhVdfNICWeCbLEcTklMFWtJdCRyA8BWnk4LKfFO0=
|
||||
github.com/android-sms-gateway/client-go v0.0.0-20240530135354-8d1ce85b9734/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
|
||||
github.com/android-sms-gateway/client-go v1.0.0 h1:TPRNHlgcEW6jThsx0y4AG1J7wH5Iry+c6h+ailrSQW4=
|
||||
github.com/android-sms-gateway/client-go v1.0.0/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
|
||||
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
|
||||
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
|
||||
@ -4,12 +4,12 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/android-sms-gateway/client-go/smsgateway"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/models"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/modules/auth"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/modules/messages"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/repositories"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/services"
|
||||
"github.com/capcom6/sms-gateway/pkg/smsgateway"
|
||||
"github.com/capcom6/sms-gateway/pkg/types"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"github.com/android-sms-gateway/client-go/smsgateway"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/modules/health"
|
||||
"github.com/capcom6/sms-gateway/internal/version"
|
||||
"github.com/capcom6/sms-gateway/pkg/maps"
|
||||
"github.com/capcom6/sms-gateway/pkg/smsgateway"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/fx"
|
||||
"go.uber.org/zap"
|
||||
|
||||
@ -5,12 +5,12 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/android-sms-gateway/client-go/smsgateway"
|
||||
"github.com/capcom6/go-infra-fx/http/apikey"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/models"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/modules/auth"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/modules/messages"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/repositories"
|
||||
"github.com/capcom6/sms-gateway/pkg/smsgateway"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/limiter"
|
||||
|
||||
@ -3,8 +3,8 @@ package handlers
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/android-sms-gateway/client-go/smsgateway"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/modules/push"
|
||||
"github.com/capcom6/sms-gateway/pkg/smsgateway"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/limiter"
|
||||
|
||||
@ -7,11 +7,11 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/android-sms-gateway/client-go/smsgateway"
|
||||
"github.com/capcom6/go-helpers/slices"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/models"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/modules/push"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/repositories"
|
||||
"github.com/capcom6/sms-gateway/pkg/smsgateway"
|
||||
"github.com/capcom6/sms-gateway/pkg/types"
|
||||
"github.com/jaevor/go-nanoid"
|
||||
"github.com/nyaruka/phonenumbers"
|
||||
|
||||
@ -4,8 +4,8 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/android-sms-gateway/client-go/smsgateway"
|
||||
"github.com/capcom6/sms-gateway/internal/sms-gateway/models"
|
||||
"github.com/capcom6/sms-gateway/pkg/smsgateway"
|
||||
)
|
||||
|
||||
func TestService_recipientsStateToModel(t *testing.T) {
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/capcom6/sms-gateway/pkg/smsgateway"
|
||||
"github.com/android-sms-gateway/client-go/smsgateway"
|
||||
)
|
||||
|
||||
const BASE_URL = "https://sms.capcom.me/api/upstream/v1"
|
||||
|
||||
@ -1,88 +0,0 @@
|
||||
package smsgateway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const BASE_URL = "https://sms.capcom.me/api/3rdparty/v1"
|
||||
|
||||
type Config struct {
|
||||
Client *http.Client
|
||||
BaseURL string
|
||||
User string
|
||||
Password string
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
Config Config
|
||||
}
|
||||
|
||||
func NewClient(config Config) *Client {
|
||||
if config.Client == nil {
|
||||
config.Client = http.DefaultClient
|
||||
}
|
||||
if config.BaseURL == "" {
|
||||
config.BaseURL = BASE_URL
|
||||
}
|
||||
|
||||
return &Client{Config: config}
|
||||
}
|
||||
|
||||
func (c *Client) Send(ctx context.Context, message Message) (MessageState, error) {
|
||||
path := "/message"
|
||||
resp := MessageState{}
|
||||
|
||||
return resp, c.doRequest(ctx, http.MethodPost, path, map[string]string{}, &message, &resp)
|
||||
}
|
||||
|
||||
func (c *Client) GetState(ctx context.Context, messageID string) (MessageState, error) {
|
||||
path := fmt.Sprintf("/message/%s", messageID)
|
||||
resp := MessageState{}
|
||||
|
||||
return resp, c.doRequest(ctx, http.MethodGet, path, map[string]string{}, nil, &resp)
|
||||
}
|
||||
|
||||
func (c *Client) doRequest(ctx context.Context, method, path string, headers map[string]string, payload, response any) error {
|
||||
var reqBody io.Reader = nil
|
||||
if payload != nil {
|
||||
jsonBytes, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reqBody = strings.NewReader(string(jsonBytes))
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, c.Config.BaseURL+path, reqBody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.SetBasicAuth(c.Config.User, c.Config.Password)
|
||||
if reqBody != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
for k, v := range headers {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
|
||||
resp, err := c.Config.Client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
_, _ = io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
if resp.StatusCode >= 400 {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return fmt.Errorf("unexpected status code %d with body %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
return json.NewDecoder(resp.Body).Decode(&response)
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
package smsgateway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestClient_Send(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/message" {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if r.Header.Get("Content-Type") != "application/json" {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
req, _ := io.ReadAll(r.Body)
|
||||
defer r.Body.Close()
|
||||
|
||||
if string(req) != `{"message":"","phoneNumbers":null}` {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
_, _ = w.Write(req)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
_, _ = w.Write([]byte(`{}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := NewClient(Config{
|
||||
BaseURL: server.URL,
|
||||
})
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
message Message
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
c *Client
|
||||
args args
|
||||
want MessageState
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "Success",
|
||||
c: client,
|
||||
args: args{
|
||||
ctx: context.TODO(),
|
||||
message: Message{},
|
||||
},
|
||||
want: MessageState{},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := tt.c.Send(tt.args.ctx, tt.args.message)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("Client.Send() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("Client.Send() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1,86 +0,0 @@
|
||||
package smsgateway
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
ProcessingStatePending ProcessingState = "Pending" // Pending
|
||||
ProcessingStateProcessed ProcessingState = "Processed" // Processed (received by device)
|
||||
ProcessingStateSent ProcessingState = "Sent" // Sent
|
||||
ProcessingStateDelivered ProcessingState = "Delivered" // Delivered
|
||||
ProcessingStateFailed ProcessingState = "Failed" // Failed
|
||||
)
|
||||
|
||||
var allProcessStates = map[ProcessingState]struct{}{
|
||||
ProcessingStatePending: {},
|
||||
ProcessingStateProcessed: {},
|
||||
ProcessingStateSent: {},
|
||||
ProcessingStateDelivered: {},
|
||||
ProcessingStateFailed: {},
|
||||
}
|
||||
|
||||
// Device
|
||||
type Device struct {
|
||||
ID string `json:"id" example:"PyDmBQZZXYmyxMwED8Fzy"` // ID
|
||||
Name string `json:"name" example:"My Device"` // Name
|
||||
CreatedAt time.Time `json:"createdAt" example:"2020-01-01T00:00:00Z"` // Created at (read only)
|
||||
UpdatedAt time.Time `json:"updatedAt" example:"2020-01-01T00:00:00Z"` // Updated at (read only)
|
||||
DeletedAt *time.Time `json:"deletedAt,omitempty" example:"2020-01-01T00:00:00Z"` // Deleted at (read only)
|
||||
|
||||
LastSeen time.Time `json:"lastSeen" example:"2020-01-01T00:00:00Z"` // Last seen at (read only)
|
||||
}
|
||||
|
||||
// Message
|
||||
type Message struct {
|
||||
ID string `json:"id,omitempty" validate:"omitempty,max=36" example:"PyDmBQZZXYmyxMwED8Fzy"` // ID (if not set - will be generated)
|
||||
Message string `json:"message" validate:"required,max=65535" example:"Hello World!"` // Content
|
||||
SimNumber *uint8 `json:"simNumber,omitempty" validate:"omitempty,max=3" example:"1"` // SIM card number (1-3)
|
||||
WithDeliveryReport *bool `json:"withDeliveryReport,omitempty" example:"true"` // With delivery report
|
||||
IsEncrypted bool `json:"isEncrypted,omitempty" example:"true"` // Is encrypted
|
||||
PhoneNumbers []string `json:"phoneNumbers" validate:"required,min=1,max=100,dive,required,min=10,max=128" example:"79990001234"` // Recipients (phone numbers)
|
||||
|
||||
TTL *uint64 `json:"ttl,omitempty" validate:"omitempty,min=5" example:"86400"` // Time to live in seconds (conflicts with `validUntil`)
|
||||
ValidUntil *time.Time `json:"validUntil,omitempty" example:"2020-01-01T00:00:00Z"` // Valid until (conflicts with `ttl`)
|
||||
}
|
||||
|
||||
func (m Message) Validate() error {
|
||||
if m.TTL != nil && m.ValidUntil != nil {
|
||||
return fmt.Errorf("%w: ttl and validUntil", ErrConflictFields)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Message state
|
||||
type MessageState struct {
|
||||
ID string `json:"id,omitempty" validate:"omitempty,max=36" example:"PyDmBQZZXYmyxMwED8Fzy"` // Message ID
|
||||
State ProcessingState `json:"state" validate:"required" example:"Pending"` // State
|
||||
IsHashed bool `json:"isHashed" example:"false"` // Hashed
|
||||
IsEncrypted bool `json:"isEncrypted" example:"false"` // Encrypted
|
||||
Recipients []RecipientState `json:"recipients" validate:"required,min=1,dive"` // Recipients states
|
||||
States map[string]time.Time `json:"states"` // History of states
|
||||
}
|
||||
|
||||
func (m MessageState) Validate() error {
|
||||
for k := range m.States {
|
||||
if _, ok := allProcessStates[ProcessingState(k)]; !ok {
|
||||
return fmt.Errorf("invalid state value: %s", k)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Recipient state
|
||||
type RecipientState struct {
|
||||
PhoneNumber string `json:"phoneNumber" validate:"required,min=10,max=128" example:"79990001234"` // Phone number or first 16 symbols of SHA256 hash
|
||||
State ProcessingState `json:"state" validate:"required" example:"Pending"` // State
|
||||
Error *string `json:"error,omitempty" example:"timeout"` // Error (for `Failed` state)
|
||||
}
|
||||
|
||||
// Push notification
|
||||
type PushNotification struct {
|
||||
Token string `json:"token" validate:"required" example:"PyDmBQZZXYmyxMwED8Fzy"` // Device FCM token
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
package smsgateway
|
||||
|
||||
// Device registration request
|
||||
type MobileRegisterRequest struct {
|
||||
Name *string `json:"name,omitempty" validate:"omitempty,max=128" example:"Android Phone"` // Device name
|
||||
PushToken *string `json:"pushToken" validate:"omitempty,max=256" example:"gHz-T6NezDlOfllr7F-Be"` // FCM token
|
||||
}
|
||||
|
||||
// Device update request
|
||||
type MobileUpdateRequest struct {
|
||||
Id string `json:"id" example:"QslD_GefqiYV6RQXdkM6V"` // ID
|
||||
PushToken string `json:"pushToken" validate:"omitempty,max=256" example:"gHz-T6NezDlOfllr7F-Be"` // FCM token
|
||||
}
|
||||
|
||||
// Push request
|
||||
type UpstreamPushRequest = []PushNotification
|
||||
@ -1,16 +0,0 @@
|
||||
package smsgateway
|
||||
|
||||
// Device registration response
|
||||
type MobileRegisterResponse struct {
|
||||
Id string `json:"id" example:"QslD_GefqiYV6RQXdkM6V"` // New device ID
|
||||
Token string `json:"token" example:"bP0ZdK6rC6hCYZSjzmqhQ"` // Device access token
|
||||
Login string `json:"login" example:"VQ4GII"` // User login
|
||||
Password string `json:"password" example:"cp2pydvxd2zwpx"` // User password
|
||||
}
|
||||
|
||||
// Error response
|
||||
type ErrorResponse struct {
|
||||
Message string `json:"message" example:"An error occurred"` // Error message
|
||||
Code int32 `json:"code,omitempty"` // Error code
|
||||
Data any `json:"data,omitempty"` // Error context
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
package smsgateway
|
||||
|
||||
type HealthStatus string
|
||||
|
||||
const (
|
||||
HealthStatusPass HealthStatus = "pass"
|
||||
HealthStatusWarn HealthStatus = "warn"
|
||||
HealthStatusFail HealthStatus = "fail"
|
||||
)
|
||||
|
||||
// Details of a health check.
|
||||
type HealthCheck struct {
|
||||
// A human-readable description of the check.
|
||||
Description string `json:"description,omitempty"`
|
||||
// Unit of measurement for the observed value.
|
||||
ObservedUnit string `json:"observedUnit,omitempty"`
|
||||
// Observed value of the check.
|
||||
ObservedValue int `json:"observedValue"`
|
||||
// Status of the check.
|
||||
// It can be one of the following values: "pass", "warn", or "fail".
|
||||
Status HealthStatus `json:"status"`
|
||||
}
|
||||
|
||||
// Map of check names to their respective details.
|
||||
type HealthChecks map[string]HealthCheck
|
||||
|
||||
// Health status of the application.
|
||||
type HealthResponse struct {
|
||||
// Overall status of the application.
|
||||
// It can be one of the following values: "pass", "warn", or "fail".
|
||||
Status HealthStatus `json:"status"`
|
||||
// Version of the application.
|
||||
Version string `json:"version,omitempty"`
|
||||
// Release ID of the application.
|
||||
// It is used to identify the version of the application.
|
||||
ReleaseID int `json:"releaseId,omitempty"`
|
||||
// A map of check names to their respective details.
|
||||
Checks HealthChecks `json:"checks,omitempty"`
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
package smsgateway
|
||||
|
||||
import "errors"
|
||||
|
||||
type ProcessingState string
|
||||
|
||||
var ErrConflictFields = errors.New("conflict fields")
|
||||
Loading…
x
Reference in New Issue
Block a user