123 lines
3.7 KiB
Go
123 lines
3.7 KiB
Go
package resource
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
activityv1 "hyapp.local/api/proto/activity/v1"
|
|
walletv1 "hyapp.local/api/proto/wallet/v1"
|
|
)
|
|
|
|
const (
|
|
resourceGrantNoticeTitle = "System Gift"
|
|
resourceGrantNoticeBody = "You received the following system-granted resources."
|
|
)
|
|
|
|
type resourceNoticeSnapshot struct {
|
|
ResourceType string
|
|
Name string
|
|
AssetURL string
|
|
PreviewURL string
|
|
MetadataJSON string
|
|
}
|
|
|
|
func (h *Handler) createResourceGrantNotice(ctx context.Context, requestID string, appCode string, grant *walletv1.ResourceGrant) error {
|
|
if grant == nil {
|
|
return fmt.Errorf("resource grant response is empty")
|
|
}
|
|
return h.createResourceBatchGrantNotice(ctx, requestID, appCode, grant.GetGrantId(), grant.GetTargetUserId(), []*walletv1.ResourceGrant{grant})
|
|
}
|
|
|
|
func (h *Handler) createResourceBatchGrantNotice(ctx context.Context, requestID string, appCode string, commandID string, targetUserID int64, grants []*walletv1.ResourceGrant) error {
|
|
if h.activity == nil {
|
|
// Tests and isolated local handlers may omit integrations; the production constructor always wires activity-service.
|
|
return nil
|
|
}
|
|
snapshots, err := resourceNoticeSnapshots(grants)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
body := resourceGrantNoticeBody
|
|
imageURLs := resourceNoticeImageURLs(snapshots)
|
|
if len(grants) == 1 && len(snapshots) == 1 && strings.EqualFold(strings.TrimSpace(snapshots[0].ResourceType), resourceTypeVIPTrialCard) {
|
|
level := vipTrialLevel(snapshots[0].MetadataJSON)
|
|
body = "You received a VIP trial card."
|
|
if level > 0 {
|
|
body = fmt.Sprintf("You received a VIP%d trial card.", level)
|
|
}
|
|
imageURLs = nil
|
|
}
|
|
producerEventID := "resource_grant:" + strings.TrimSpace(commandID)
|
|
_, err = h.activity.CreateInboxMessage(ctx, &activityv1.CreateInboxMessageRequest{
|
|
Meta: &activityv1.RequestMeta{RequestId: strings.TrimSpace(requestID), Caller: "admin-server", AppCode: strings.TrimSpace(appCode)},
|
|
TargetUserId: targetUserID,
|
|
Producer: "admin-server",
|
|
ProducerEventId: producerEventID,
|
|
ProducerEventType: "AdminResourceGranted",
|
|
MessageType: "system",
|
|
AggregateType: "resource_grant",
|
|
AggregateId: strings.TrimSpace(commandID),
|
|
Title: resourceGrantNoticeTitle,
|
|
Summary: body,
|
|
Body: body,
|
|
ImageUrl: firstNoticeImageURL(imageURLs),
|
|
ImageUrls: imageURLs,
|
|
})
|
|
return err
|
|
}
|
|
|
|
func resourceNoticeSnapshots(grants []*walletv1.ResourceGrant) ([]resourceNoticeSnapshot, error) {
|
|
result := make([]resourceNoticeSnapshot, 0)
|
|
for _, grant := range grants {
|
|
if grant == nil {
|
|
continue
|
|
}
|
|
for _, item := range grant.GetItems() {
|
|
raw := strings.TrimSpace(item.GetResourceSnapshotJson())
|
|
if raw == "" || raw == "{}" {
|
|
continue
|
|
}
|
|
var snapshot resourceNoticeSnapshot
|
|
if err := json.Unmarshal([]byte(raw), &snapshot); err != nil {
|
|
return nil, fmt.Errorf("decode granted resource snapshot: %w", err)
|
|
}
|
|
result = append(result, snapshot)
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func resourceNoticeImageURLs(snapshots []resourceNoticeSnapshot) []string {
|
|
result := make([]string, 0, len(snapshots))
|
|
for _, snapshot := range snapshots {
|
|
url := strings.TrimSpace(snapshot.PreviewURL)
|
|
if url == "" {
|
|
url = strings.TrimSpace(snapshot.AssetURL)
|
|
}
|
|
if url == "" {
|
|
continue
|
|
}
|
|
result = append(result, url)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func vipTrialLevel(metadataJSON string) int32 {
|
|
var metadata struct {
|
|
VIPLevel int32 `json:"vip_level"`
|
|
}
|
|
if err := json.Unmarshal([]byte(strings.TrimSpace(metadataJSON)), &metadata); err != nil {
|
|
return 0
|
|
}
|
|
return metadata.VIPLevel
|
|
}
|
|
|
|
func firstNoticeImageURL(imageURLs []string) string {
|
|
if len(imageURLs) == 0 {
|
|
return ""
|
|
}
|
|
return imageURLs[0]
|
|
}
|