2025-01-27 12:09:39 +03:00
|
|
|
package push_common
|
|
|
|
|
2025-01-27 14:31:18 +03:00
|
|
|
import (
|
2025-02-06 10:51:07 +03:00
|
|
|
"context"
|
2025-02-06 12:17:09 +03:00
|
|
|
"encoding/json"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
2025-01-27 14:31:18 +03:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"git.bit5.ru/backend/errors"
|
|
|
|
)
|
|
|
|
|
2025-01-27 12:53:40 +03:00
|
|
|
type PushId uint32
|
|
|
|
|
|
|
|
func (id PushId) String() string {
|
|
|
|
return uint32ToString(uint32(id))
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2025-01-27 13:10:03 +03:00
|
|
|
type PushPreview struct {
|
|
|
|
Id PushId `json:"id"`
|
|
|
|
Ctime uint32 `json:"ctime"`
|
|
|
|
Stime uint32 `json:"stime"`
|
|
|
|
Status int `json:"status"`
|
|
|
|
Info string `json:"info,omitempty"`
|
|
|
|
MaxVersion string `json:"maxVersion,omitempty"`
|
|
|
|
Platforms []uint32 `json:"platforms,omitempty"`
|
|
|
|
PlayersIds []uint32 `json:"playersIds,omitempty"`
|
|
|
|
Title string `json:"title"`
|
|
|
|
Message string `json:"message"`
|
|
|
|
Total int `json:"total"`
|
|
|
|
Sent int `json:"sent"`
|
|
|
|
Fails int `json:"fails"`
|
|
|
|
ForTest bool `json:"forTest,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2025-01-27 14:31:18 +03:00
|
|
|
type PushDef struct {
|
|
|
|
MaxVersion string `json:"maxVersion"`
|
|
|
|
Platforms []uint32 `json:"platforms"`
|
|
|
|
PlayersIds []uint32 `json:"playersIds"`
|
|
|
|
Stime uint32 `json:"stime"`
|
|
|
|
TextVariants []*TextVariant `json:"textVariants"`
|
|
|
|
ForTest bool `json:"forTest"`
|
|
|
|
ImageUrl string `json:"imageUrl"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pushDef *PushDef) Validate() error {
|
|
|
|
if len(pushDef.TextVariants) == 0 {
|
|
|
|
return errors.New("No text variants")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pushDef *PushDef) Info() string {
|
|
|
|
var strs []string
|
|
|
|
if len(pushDef.Platforms) > 0 {
|
|
|
|
strs = append(strs, "Platforms: "+sliceUint32ToString(pushDef.Platforms, ","))
|
|
|
|
}
|
|
|
|
if len(pushDef.MaxVersion) > 0 {
|
|
|
|
strs = append(strs, "Max.ver: "+pushDef.MaxVersion)
|
|
|
|
}
|
|
|
|
if len(pushDef.PlayersIds) > 0 {
|
|
|
|
playersIdsStr := sliceUint32ToString(pushDef.PlayersIds, ",")
|
|
|
|
strs = append(strs, "Plr.ids: "+playersIdsStr)
|
|
|
|
}
|
|
|
|
return strings.Join(strs, "; ")
|
|
|
|
}
|
|
|
|
|
|
|
|
func sliceUint32ToString(nums []uint32, sep string) string {
|
|
|
|
strs := make([]string, 0, len(nums))
|
|
|
|
for _, num := range nums {
|
|
|
|
str := strconv.FormatUint(uint64(num), 10)
|
|
|
|
strs = append(strs, str)
|
|
|
|
}
|
|
|
|
return strings.Join(strs, sep)
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
type IncomingPushInfo struct {
|
|
|
|
Id int `json:"id"`
|
|
|
|
MaxVersion string `json:"maxVersion"`
|
|
|
|
Platforms []uint32 `json:"platforms"`
|
|
|
|
PlayersIds []uint32 `json:"playersIds"`
|
|
|
|
TextVariants []*TextVariant `json:"textVariants"`
|
|
|
|
ImageUrl string `json:"imageUrl"`
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2025-01-27 12:09:39 +03:00
|
|
|
type TextVariant struct {
|
|
|
|
Lang int `json:"lang"`
|
|
|
|
Title string `json:"title"`
|
|
|
|
Message string `json:"message"`
|
|
|
|
}
|
2025-02-06 10:51:07 +03:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
type PushRequest struct {
|
|
|
|
Title string `json:"title"`
|
|
|
|
Message string `json:"message"`
|
|
|
|
Info string `json:"info"`
|
|
|
|
Label string `json:"label"` //Note: label for firebase
|
|
|
|
Ttl uint32 `json:"ttl"`
|
|
|
|
Jobs []PushJobRequest `json:"jobs"`
|
|
|
|
ImageUrl string `json:"imageUrl"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *PushRequest) DeviceTokenAmount() uint32 {
|
|
|
|
return jobRequests_deviceTokenAmount(r.Jobs)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *PushRequest) Validate() error {
|
|
|
|
return validateJobsRequests(r.Jobs)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *PushRequest) FindJobByLang(lang int) *PushJobRequest {
|
|
|
|
for _, j := range r.Jobs {
|
|
|
|
if j.Language == lang {
|
|
|
|
return &j
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *PushRequest) GetPlatforms() []Platform {
|
|
|
|
var platforms []Platform
|
|
|
|
|
|
|
|
for _, jobRequest := range r.Jobs {
|
|
|
|
p := jobRequest.Platform
|
|
|
|
if !PlatformsContain(platforms, p) {
|
|
|
|
platforms = append(platforms, p)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return platforms
|
|
|
|
}
|
|
|
|
|
|
|
|
type PushLaunchRequest struct {
|
|
|
|
Id int `json:"id"`
|
|
|
|
JobRequests []PushJobRequest `json:"jobs"` // Длина среза jobRequests может быть равна 0.
|
|
|
|
}
|
|
|
|
|
|
|
|
//func (r *PushLaunchRequest) jobAmount() uint32 {
|
|
|
|
// return uint32(len(r.JobRequests))
|
|
|
|
//}
|
|
|
|
|
|
|
|
func (r *PushLaunchRequest) DeviceTokenAmount() uint32 {
|
|
|
|
return jobRequests_deviceTokenAmount(r.JobRequests)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *PushLaunchRequest) Validate(ctx context.Context) error {
|
|
|
|
return validateJobsRequests(r.JobRequests)
|
|
|
|
}
|
|
|
|
|
|
|
|
func validateJobsRequests(jobRequests []PushJobRequest) error {
|
|
|
|
for _, jobRequest := range jobRequests {
|
|
|
|
if err := jobRequest.Validate(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type PushJobRequest struct {
|
|
|
|
Message string `json:"message"`
|
|
|
|
Title string `json:"title"`
|
|
|
|
Platform Platform `json:"platform"`
|
|
|
|
Language int `json:"language"`
|
|
|
|
Utc_delta int `json:"utc_delta"`
|
|
|
|
Device_tokens []string `json:"device_tokens"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (j *PushJobRequest) Validate() error {
|
|
|
|
if len(j.Message) == 0 {
|
|
|
|
return errors.New("No message")
|
|
|
|
}
|
|
|
|
if len(j.Device_tokens) == 0 {
|
|
|
|
return errors.New("No device tokens")
|
|
|
|
}
|
|
|
|
if j.Platform == PlatformUnknown {
|
|
|
|
return errors.New("No platform")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (req *PushJobRequest) deviceTokenAmount() uint32 {
|
|
|
|
return uint32(len(req.Device_tokens))
|
|
|
|
}
|
|
|
|
|
|
|
|
func jobRequests_deviceTokenAmount(jobRequests []PushJobRequest) uint32 {
|
|
|
|
var total uint32 = 0
|
|
|
|
for _, jobRequest := range jobRequests {
|
|
|
|
total += jobRequest.deviceTokenAmount()
|
|
|
|
}
|
|
|
|
return total
|
|
|
|
}
|
2025-02-06 11:51:43 +03:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
type PushPayload struct {
|
|
|
|
ImageUrl string `json:"imageUrl"`
|
|
|
|
TextVariants []*TextVariant `json:"textVariants"`
|
|
|
|
}
|
2025-02-06 12:17:09 +03:00
|
|
|
|
|
|
|
func ReadPayloadFromRequest(request *http.Request, payload *PushPayload) error {
|
|
|
|
b, err := io.ReadAll(request.Body)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if b == nil {
|
|
|
|
return errors.New("Can not read text variants. Request body bytes is nil.")
|
|
|
|
}
|
|
|
|
|
|
|
|
return json.Unmarshal(b, payload)
|
|
|
|
}
|