push_common/push_common.go

292 lines
8.0 KiB
Go
Raw Permalink Normal View History

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
2025-02-06 12:53:35 +03:00
func FindTextVariantByLang(textVariants []*TextVariant, lang int) *TextVariant {
for _, textVariant := range textVariants {
if textVariant.Lang == lang {
return textVariant
}
}
return nil
}
func ReadTextVariantsFromRequest(request *http.Request, textVariants *[]*TextVariant) 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, textVariants)
}
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)
}
2025-02-06 13:46:39 +03:00
//-----------------------------------------------------------------------------
type Push struct {
Id uint32 `json:"id"`
Status int `json:"status"`
Ctime uint32 `json:"ctime"`
Mtime uint32 `json:"mtime"`
Ttl uint32 `json:"ttl"`
Stime uint32 `json:"stime"`
Srtime uint32 `json:"srtime"`
Info string `json:"info"`
Label string `json:"label"`
MaxVersion string `json:"maxVersion,omitempty"`
Platforms []uint32 `json:"platforms,omitempty"`
PlayersIds []uint32 `json:"playersIds,omitempty"`
Title string `json:"title"`
Message string `json:"message"`
TextVariants []*TextVariant `json:"textVariants"` // For incoming push only.
Jobs []*PushJob `json:"jobs"` // Incoming push has no jobs.
Total int `json:"total"`
Sent int `json:"sent"` // Incoming push has not field "Sent".
Fails int `json:"fails"` // Incoming push has not field "Fails".
ForTest bool `json:"forTest,omitempty"`
ImageUrl string `json:"imageUrl,omitempty"`
}
func (push *Push) IsDone() bool {
return push.Total == (push.Sent + push.Fails)
}
//-----------------------------------------------------------------------------
type JobId uint32
type PushJob struct {
Id JobId `json:"id"`
Platform Platform `json:"platform"`
Message string `json:"message"`
Title string `json:"title"`
Language int `json:"language"`
Utc_delta int `json:"utc_delta"`
Total int `json:"total"`
Sent int `json:"sent"`
Fails int `json:"fails"`
}
func (job *PushJob) IsDone() bool {
return job.Total == (job.Sent + job.Fails)
}