feat(jpush): add vendor-specific message classification support for push notifications
All checks were successful
Build Backend / build (push) Successful in 3m4s
Build Backend / build-docker (push) Successful in 1m15s

- Add OPPO category/notify_level support (2024.11.20 regulation: category required when notify_level present)
- Add Honor importance field (NORMAL=service/LOW=marketing) for notification classification
- Add vivo category field (IM/ACCOUNT) for message scenario identification
- Set Xiaomi channel/template defaults in code (system=153609, chat=153608, templates P10761/M10289)
- Add classification option to JPush push payloads (0=operation, 1=system)
- Update xiaomi template keywords mapping to match actual template placeholders
- Add keyword search support for GetFollowers and GetFollowing endpoints
- Bind new config fields to environment variables for OPPO/Honor/vivo
This commit is contained in:
lafay
2026-06-18 19:41:32 +08:00
parent 5b83f98fb8
commit 821e066446
13 changed files with 637 additions and 66 deletions

View File

@@ -292,7 +292,7 @@ func (c *Client) Push(payload map[string]any) (*PushResponse, *RateLimitInfo, er
return result, rateLimit, parseErr
}
func (c *Client) PushByRegistrationIDs(registrationIDs []string, notification *Notification, tpc *ThirdPartyChannel) (*PushResponse, error) {
func (c *Client) PushByRegistrationIDs(registrationIDs []string, notification *Notification, classification int, tpc *ThirdPartyChannel) (*PushResponse, error) {
if len(registrationIDs) == 0 {
return nil, fmt.Errorf("registration IDs cannot be empty")
}
@@ -310,7 +310,7 @@ func (c *Client) PushByRegistrationIDs(registrationIDs []string, notification *N
"platform": "all",
"audience": map[string]any{"registration_id": registrationIDs},
"notification": notification,
"options": c.buildOptions(tpc),
"options": c.buildOptions(classification, tpc),
}
var result *PushResponse
@@ -337,7 +337,7 @@ func (c *Client) PushByRegistrationIDs(registrationIDs []string, notification *N
return result, nil
}
func (c *Client) PushByAliases(aliases []string, notification *Notification, tpc *ThirdPartyChannel) (*PushResponse, error) {
func (c *Client) PushByAliases(aliases []string, notification *Notification, classification int, tpc *ThirdPartyChannel) (*PushResponse, error) {
if len(aliases) == 0 {
return nil, fmt.Errorf("aliases cannot be empty")
}
@@ -355,7 +355,7 @@ func (c *Client) PushByAliases(aliases []string, notification *Notification, tpc
"platform": "all",
"audience": map[string]any{"alias": aliases},
"notification": notification,
"options": c.buildOptions(tpc),
"options": c.buildOptions(classification, tpc),
}
result, _, err := c.Push(payload)
@@ -374,7 +374,7 @@ func (c *Client) PushByAliases(aliases []string, notification *Notification, tpc
return result, nil
}
func (c *Client) PushAll(notification *Notification, tpc *ThirdPartyChannel) (*PushResponse, error) {
func (c *Client) PushAll(notification *Notification, classification int, tpc *ThirdPartyChannel) (*PushResponse, error) {
c.logger.Info("jpush push all",
zap.String("title", notification.Android.Title),
zap.String("alert", notification.Alert),
@@ -384,7 +384,7 @@ func (c *Client) PushAll(notification *Notification, tpc *ThirdPartyChannel) (*P
"platform": "all",
"audience": "all",
"notification": notification,
"options": c.buildOptions(tpc),
"options": c.buildOptions(classification, tpc),
}
result, _, err := c.Push(payload)
@@ -402,9 +402,11 @@ func (c *Client) PushAll(notification *Notification, tpc *ThirdPartyChannel) (*P
}
// buildOptions 构造 push payload 的 options 部分
// 当 tpc 非空时加入 third_party_channel 字段,用于向各厂商下发 channel_id
func (c *Client) buildOptions(tpc *ThirdPartyChannel) map[string]any {
// classification 为消息分类0=运营消息1=系统消息)
// tpc 非空时加入 third_party_channel 字段,用于向各厂商下发 channel_id
func (c *Client) buildOptions(classification int, tpc *ThirdPartyChannel) map[string]any {
opts := map[string]any{
"classification": classification,
"time_to_live": 86400,
"apns_production": c.production,
}