PushNotificationService.java
8.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
package com.ecommerce.notification.service;
import com.ecommerce.notification.model.Notification;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class PushNotificationService {
private final ObjectMapper objectMapper;
public boolean sendPushNotification(Notification notification) {
try {
String title = notification.getSubject(); // 使用 subject 作为标题
String body = notification.getContent(); // 使用 content 作为内容
// 将 metadata 字符串转换为 Map
Map<String, Object> metadata = convertMetadataToMap(notification.getMetadata());
// 根据类型发送推送通知
switch (notification.getType().toUpperCase()) {
case "PUSH":
case "FCM":
return sendViaFcm(notification.getDeviceToken(), title, body, metadata);
case "APNS":
return sendViaApns(notification.getDeviceToken(), title, body, metadata);
case "WEB_PUSH":
return sendViaWebPush(notification.getDeviceToken(), title, body, metadata);
case "IN_APP":
return sendInAppNotification(notification.getUserId(), title, body, metadata);
default:
log.warn("Unsupported push notification type: {}", notification.getType());
return false;
}
} catch (Exception e) {
log.error("Failed to send push notification: {}", e.getMessage());
return false;
}
}
private boolean sendViaFcm(String deviceToken, String title, String body, Map<String, Object> metadata) {
try {
if (deviceToken == null || deviceToken.trim().isEmpty()) {
log.warn("FCM device token is missing");
return false;
}
// FCM 推送实现
log.info("Sending FCM notification to: {}, title: {}, body: {}", deviceToken, title, body);
// 构建 FCM 消息
Map<String, Object> message = new HashMap<>();
message.put("token", deviceToken);
Map<String, Object> notificationData = new HashMap<>();
notificationData.put("title", title);
notificationData.put("body", body);
Map<String, Object> data = new HashMap<>();
data.put("metadata", metadata);
message.put("notification", notificationData);
message.put("data", data);
// 模拟 FCM 推送
// 在实际实现中,这里会调用 FCM API
// fcmService.send(message);
log.info("FCM notification sent successfully to: {}", deviceToken);
return true;
} catch (Exception e) {
log.error("FCM notification failed for token {}: {}", deviceToken, e.getMessage());
return false;
}
}
private boolean sendViaApns(String deviceToken, String title, String body, Map<String, Object> metadata) {
try {
if (deviceToken == null || deviceToken.trim().isEmpty()) {
log.warn("APNS device token is missing");
return false;
}
// APNS 推送实现
log.info("Sending APNS notification to: {}, title: {}, body: {}", deviceToken, title, body);
// 构建 APNS 消息
Map<String, Object> aps = new HashMap<>();
aps.put("alert", new HashMap<String, Object>() {{
put("title", title);
put("body", body);
}});
aps.put("sound", "default");
aps.put("badge", 1);
Map<String, Object> message = new HashMap<>();
message.put("aps", aps);
message.put("metadata", metadata);
// 模拟 APNS 推送
// 在实际实现中,这里会调用 APNS API
// apnsService.send(deviceToken, message);
log.info("APNS notification sent successfully to: {}", deviceToken);
return true;
} catch (Exception e) {
log.error("APNS notification failed for token {}: {}", deviceToken, e.getMessage());
return false;
}
}
private boolean sendViaWebPush(String deviceToken, String title, String body, Map<String, Object> metadata) {
try {
if (deviceToken == null || deviceToken.trim().isEmpty()) {
log.warn("Web Push subscription is missing");
return false;
}
// Web Push 推送实现
log.info("Sending Web Push notification to: {}, title: {}, body: {}", deviceToken, title, body);
// 构建 Web Push 消息
Map<String, Object> payload = new HashMap<>();
payload.put("title", title);
payload.put("body", body);
payload.put("icon", "/icon.png");
payload.put("data", metadata);
// 模拟 Web Push 推送
// 在实际实现中,这里会使用 Web Push 库
// webPushService.send(deviceToken, payload);
log.info("Web Push notification sent successfully to: {}", deviceToken);
return true;
} catch (Exception e) {
log.error("Web Push notification failed for subscription {}: {}", deviceToken, e.getMessage());
return false;
}
}
private boolean sendInAppNotification(Long userId, String title, String body, Map<String, Object> metadata) {
try {
if (userId == null) {
log.warn("User ID is missing for in-app notification");
return false;
}
// 应用内通知实现
log.info("Sending in-app notification to user: {}, title: {}, body: {}", userId, title, body);
// 在实际实现中,这里会保存通知到数据库并通过 WebSocket 推送到前端
// inAppNotificationService.saveAndSend(userId, title, body, metadata);
log.info("In-app notification sent successfully to user: {}", userId);
return true;
} catch (Exception e) {
log.error("In-app notification failed for user {}: {}", userId, e.getMessage());
return false;
}
}
private Map<String, Object> convertMetadataToMap(String metadata) {
if (metadata == null || metadata.trim().isEmpty()) {
return new HashMap<>();
}
try {
return objectMapper.readValue(metadata, new TypeReference<Map<String, Object>>() {});
} catch (Exception e) {
log.warn("Failed to parse metadata JSON: {}, using empty map", e.getMessage());
return new HashMap<>();
}
}
// 添加重载方法以支持不同的参数组合
public boolean sendViaFcm(String deviceToken, String title, String body) {
return sendViaFcm(deviceToken, title, body, new HashMap<>());
}
public boolean sendViaApns(String deviceToken, String title, String body) {
return sendViaApns(deviceToken, title, body, new HashMap<>());
}
public boolean sendViaWebPush(String deviceToken, String title, String body) {
return sendViaWebPush(deviceToken, title, body, new HashMap<>());
}
public boolean sendInAppNotification(Long userId, String title, String body) {
return sendInAppNotification(userId, title, body, new HashMap<>());
}
// 批量发送方法
public int sendBulkPushNotifications(Iterable<Notification> notifications) {
int successCount = 0;
for (Notification notification : notifications) {
if (sendPushNotification(notification)) {
successCount++;
}
}
return successCount;
}
}