diff --git a/opush-server-sdk-1.1.0.jar b/opush-server-sdk-1.1.0.jar new file mode 100644 index 0000000..81ac628 Binary files /dev/null and b/opush-server-sdk-1.1.0.jar differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..120c905 --- /dev/null +++ b/pom.xml @@ -0,0 +1,85 @@ + + + 4.0.0 + + com.oppo.push + oppo-push-server + 1.0.0 + jar + + OPPO Push Server + OPPO推送服务测试后台 + + + 1.8 + 1.8 + 1.8 + UTF-8 + 2.7.0 + + + + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot.version} + + + + + org.springframework.boot + spring-boot-configuration-processor + ${spring-boot.version} + true + + + + + com.oppo.push + opush-server-sdk + 1.1.0 + system + ${project.basedir}/opush-server-sdk-1.1.0.jar + + + + + org.apache.httpcomponents + httpclient + 4.5.13 + + + + + com.alibaba + fastjson + 1.2.83 + + + + + org.projectlombok + lombok + 1.18.24 + provided + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + true + + + + + + diff --git a/src/main/java/com/oppo/push/OppoPushApplication.java b/src/main/java/com/oppo/push/OppoPushApplication.java new file mode 100644 index 0000000..d57be47 --- /dev/null +++ b/src/main/java/com/oppo/push/OppoPushApplication.java @@ -0,0 +1,21 @@ +package com.oppo.push; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * OPPO推送服务主应用 + */ +@SpringBootApplication +public class OppoPushApplication { + + public static void main(String[] args) { + SpringApplication.run(OppoPushApplication.class, args); + System.out.println("========================================"); + System.out.println("OPPO推送服务已启动"); + System.out.println("API地址: http://localhost:8080/api/push"); + System.out.println("健康检查: http://localhost:8080/api/push/health"); + System.out.println("========================================"); + } +} + diff --git a/src/main/java/com/oppo/push/config/OppoPushConfig.java b/src/main/java/com/oppo/push/config/OppoPushConfig.java new file mode 100644 index 0000000..e319cd8 --- /dev/null +++ b/src/main/java/com/oppo/push/config/OppoPushConfig.java @@ -0,0 +1,44 @@ +package com.oppo.push.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * OPPO推送服务配置类 + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "oppo.push") +public class OppoPushConfig { + /** + * 应用Key + */ + private String appKey; + + /** + * 应用密钥 + */ + private String appSecret; + + /** + * 主密钥 + */ + private String masterSecret; + + /** + * API地址 + */ + private String apiUrl = "https://api.push.oppo.com"; + + /** + * 通讯与服务(原私信)频道ID + */ + private String channelIdIm = "previte_message"; + + /** + * 通讯与服务(原私信)频道名称 + */ + private String channelNameIm = "消息推送"; +} + diff --git a/src/main/java/com/oppo/push/controller/PushController.java b/src/main/java/com/oppo/push/controller/PushController.java new file mode 100644 index 0000000..607be3b --- /dev/null +++ b/src/main/java/com/oppo/push/controller/PushController.java @@ -0,0 +1,75 @@ +package com.oppo.push.controller; + +import com.oppo.push.service.OppoPushService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Map; + +/** + * 推送测试控制器 + */ +@Slf4j +@RestController +@RequestMapping("/api/push") +public class PushController { + + @Autowired + private OppoPushService pushService; + + /** + * 测试发送通讯与服务(原私信)类消息 + * + * @param request 请求参数 + * @return 推送结果 + */ + @PostMapping("/send") + public Map sendMessage(@RequestBody Map request) { + String targetValue = request.get("targetValue"); // registration_id或alias + String title = request.get("title"); + String content = request.get("content"); + String messageType = request.getOrDefault("messageType", "1"); // 1:通知栏消息, 2:透传消息 + + if (targetValue == null || title == null || content == null) { + Map error = new HashMap<>(); + error.put("success", false); + error.put("message", "参数不完整:需要targetValue、title、content"); + return error; + } + + return pushService.sendMessage(targetValue, title, content, Integer.parseInt(messageType)); + } + + /** + * 获取Access Token(用于测试) + */ + @GetMapping("/token") + public Map getToken() { + try { + String token = pushService.getAccessToken(); + Map result = new HashMap<>(); + result.put("success", true); + result.put("token", token); + return result; + } catch (Exception e) { + Map result = new HashMap<>(); + result.put("success", false); + result.put("message", e.getMessage()); + return result; + } + } + + /** + * 健康检查 + */ + @GetMapping("/health") + public Map health() { + Map result = new HashMap<>(); + result.put("status", "ok"); + result.put("service", "OPPO Push Server"); + return result; + } +} + diff --git a/src/main/java/com/oppo/push/service/OppoPushService.java b/src/main/java/com/oppo/push/service/OppoPushService.java new file mode 100644 index 0000000..1084ff2 --- /dev/null +++ b/src/main/java/com/oppo/push/service/OppoPushService.java @@ -0,0 +1,212 @@ +package com.oppo.push.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.oppo.push.config.OppoPushConfig; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +/** + * OPPO推送服务类 + */ +@Slf4j +@Service +public class OppoPushService { + + @Autowired + private OppoPushConfig config; + + private String accessToken; + private long tokenExpireTime; + + /** + * 获取Access Token + */ + public String getAccessToken() { + // 如果token未过期,直接返回 + if (accessToken != null && System.currentTimeMillis() < tokenExpireTime) { + return accessToken; + } + + try { + String url = config.getApiUrl() + "/v1/auth"; + + long timestamp = System.currentTimeMillis(); + Map params = new HashMap<>(); + params.put("app_key", config.getAppKey()); + params.put("timestamp", timestamp); + params.put("sign", generateSign(config.getAppKey(), timestamp, config.getMasterSecret())); + + String response = sendPostRequest(url, JSON.toJSONString(params)); + JSONObject jsonResponse = JSON.parseObject(response); + + if (jsonResponse.getInteger("code") == 0) { + accessToken = jsonResponse.getString("data"); + // token有效期通常为24小时,这里设置为23小时,提前刷新 + tokenExpireTime = System.currentTimeMillis() + 23 * 60 * 60 * 1000; + log.info("获取Access Token成功: {}", accessToken); + return accessToken; + } else { + log.error("获取Access Token失败: {}", response); + throw new RuntimeException("获取Access Token失败: " + jsonResponse.getString("message")); + } + } catch (Exception e) { + log.error("获取Access Token异常", e); + throw new RuntimeException("获取Access Token异常", e); + } + } + + /** + * 发送通讯与服务(原私信)类消息 + * + * @param targetValue 目标值(可以是token、registration_id等) + * @param title 消息标题 + * @param content 消息内容 + * @param messageType 消息类型(1:通知栏消息, 2:透传消息) + * @return 推送结果 + */ + public Map sendMessage(String targetValue, String title, String content, int messageType) { + try { + String token = getAccessToken(); + String url = config.getApiUrl() + "/v1/message/notification/single"; + + // 构建消息体 + Map message = new HashMap<>(); + message.put("target_type", 1); // 1:registration_id, 2:alias, 3:tag + message.put("target_value", targetValue); + + // 通知栏消息参数 + Map notification = new HashMap<>(); + notification.put("title", title); + notification.put("content", content); + notification.put("click_action_type", 1); // 1:打开应用首页, 2:打开应用内页, 3:打开网页, 4:打开应用内页(Intent) + notification.put("click_action_type_value", ""); + + // 通讯与服务(原私信)类消息特殊参数 + // 根据OPPO官方文档,通讯与服务类消息需要设置channel_id和channel_name + notification.put("channel_id", config.getChannelIdIm()); // 通讯与服务频道ID: previte_message + notification.put("channel_name", config.getChannelNameIm()); // 频道名称: 消息推送 + + // extra参数(可选,用于传递额外信息) + Map extra = new HashMap<>(); + extra.put("message_type", "chat"); // 标识为私信类消息 + notification.put("extra", extra); + + message.put("notification", notification); + + // 请求头 + Map headers = new HashMap<>(); + headers.put("Content-Type", "application/json;charset=UTF-8"); + headers.put("auth_token", token); + + String response = sendPostRequestWithHeaders(url, JSON.toJSONString(message), headers); + JSONObject jsonResponse = JSON.parseObject(response); + + Map result = new HashMap<>(); + result.put("success", jsonResponse.getInteger("code") == 0); + result.put("code", jsonResponse.getInteger("code")); + result.put("message", jsonResponse.getString("message")); + result.put("data", jsonResponse.get("data")); + + log.info("发送消息结果: {}", result); + return result; + } catch (Exception e) { + log.error("发送消息异常", e); + Map result = new HashMap<>(); + result.put("success", false); + result.put("message", "发送消息异常: " + e.getMessage()); + return result; + } + } + + /** + * 发送单点推送(使用SDK方式) + */ + public Map sendSinglePush(String registrationId, String title, String content) { + try { + // 这里使用OPPO SDK的方式发送 + // 注意:需要根据实际的SDK API进行调整 + return sendMessage(registrationId, title, content, 1); + } catch (Exception e) { + log.error("发送单点推送异常", e); + Map result = new HashMap<>(); + result.put("success", false); + result.put("message", "发送单点推送异常: " + e.getMessage()); + return result; + } + } + + /** + * 生成签名 + * 签名算法:MD5(app_key + timestamp + master_secret) + */ + private String generateSign(String appKey, long timestamp, String masterSecret) { + try { + String signStr = appKey + timestamp + masterSecret; + java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); + byte[] bytes = md.digest(signStr.getBytes(StandardCharsets.UTF_8)); + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } catch (Exception e) { + throw new RuntimeException("生成签名失败", e); + } + } + + /** + * 发送POST请求 + */ + private String sendPostRequest(String url, String jsonBody) throws Exception { + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost(url); + httpPost.setHeader("Content-Type", "application/json;charset=UTF-8"); + httpPost.setEntity(new StringEntity(jsonBody, StandardCharsets.UTF_8)); + + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + HttpEntity entity = response.getEntity(); + return EntityUtils.toString(entity, StandardCharsets.UTF_8); + } finally { + httpClient.close(); + } + } + + /** + * 发送带自定义请求头的POST请求 + */ + private String sendPostRequestWithHeaders(String url, String jsonBody, Map headers) throws Exception { + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost(url); + + // 设置默认请求头 + httpPost.setHeader("Content-Type", "application/json;charset=UTF-8"); + + // 设置自定义请求头 + if (headers != null) { + headers.forEach(httpPost::setHeader); + } + + httpPost.setEntity(new StringEntity(jsonBody, StandardCharsets.UTF_8)); + + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + HttpEntity entity = response.getEntity(); + return EntityUtils.toString(entity, StandardCharsets.UTF_8); + } finally { + httpClient.close(); + } + } +} + diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..ccc2da8 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,16 @@ +# OPPO推送服务配置 +# 请在OPPO开放平台获取以下信息:https://open.oppomobile.com +oppo.push.appKey=bb0819c889ae40cd8bde5a8ad4e670fe +oppo.push.appSecret=9b5a0e6d560e406dbb70fbb4e0e38098 +oppo.push.masterSecret=9b5a0e6d560e406dbb70fbb4e0e38098 + +# 通讯与服务(原私信)频道配置 +oppo.push.channel.id.im=previte_message +oppo.push.channel.name.im=消息推送 + +# 推送服务地址 +oppo.push.api.url=https://api.push.oppo.com + +# 服务器端口 +server.port=8080 + diff --git a/target/classes/META-INF/spring-configuration-metadata.json b/target/classes/META-INF/spring-configuration-metadata.json new file mode 100644 index 0000000..a1c24db --- /dev/null +++ b/target/classes/META-INF/spring-configuration-metadata.json @@ -0,0 +1,48 @@ +{ + "groups": [ + { + "name": "oppo.push", + "type": "com.oppo.push.config.OppoPushConfig", + "sourceType": "com.oppo.push.config.OppoPushConfig" + } + ], + "properties": [ + { + "name": "oppo.push.api-url", + "type": "java.lang.String", + "description": "API地址", + "sourceType": "com.oppo.push.config.OppoPushConfig" + }, + { + "name": "oppo.push.app-key", + "type": "java.lang.String", + "description": "应用Key", + "sourceType": "com.oppo.push.config.OppoPushConfig" + }, + { + "name": "oppo.push.app-secret", + "type": "java.lang.String", + "description": "应用密钥", + "sourceType": "com.oppo.push.config.OppoPushConfig" + }, + { + "name": "oppo.push.channel-id-im", + "type": "java.lang.String", + "description": "通讯与服务(原私信)频道ID", + "sourceType": "com.oppo.push.config.OppoPushConfig" + }, + { + "name": "oppo.push.channel-name-im", + "type": "java.lang.String", + "description": "通讯与服务(原私信)频道名称", + "sourceType": "com.oppo.push.config.OppoPushConfig" + }, + { + "name": "oppo.push.master-secret", + "type": "java.lang.String", + "description": "主密钥", + "sourceType": "com.oppo.push.config.OppoPushConfig" + } + ], + "hints": [] +} \ No newline at end of file diff --git a/target/classes/application.properties b/target/classes/application.properties new file mode 100644 index 0000000..ccc2da8 --- /dev/null +++ b/target/classes/application.properties @@ -0,0 +1,16 @@ +# OPPO推送服务配置 +# 请在OPPO开放平台获取以下信息:https://open.oppomobile.com +oppo.push.appKey=bb0819c889ae40cd8bde5a8ad4e670fe +oppo.push.appSecret=9b5a0e6d560e406dbb70fbb4e0e38098 +oppo.push.masterSecret=9b5a0e6d560e406dbb70fbb4e0e38098 + +# 通讯与服务(原私信)频道配置 +oppo.push.channel.id.im=previte_message +oppo.push.channel.name.im=消息推送 + +# 推送服务地址 +oppo.push.api.url=https://api.push.oppo.com + +# 服务器端口 +server.port=8080 + diff --git a/target/classes/com/oppo/push/OppoPushApplication.class b/target/classes/com/oppo/push/OppoPushApplication.class new file mode 100644 index 0000000..63e6eff Binary files /dev/null and b/target/classes/com/oppo/push/OppoPushApplication.class differ diff --git a/target/classes/com/oppo/push/config/OppoPushConfig.class b/target/classes/com/oppo/push/config/OppoPushConfig.class new file mode 100644 index 0000000..513f608 Binary files /dev/null and b/target/classes/com/oppo/push/config/OppoPushConfig.class differ diff --git a/target/classes/com/oppo/push/controller/PushController.class b/target/classes/com/oppo/push/controller/PushController.class new file mode 100644 index 0000000..710aa03 Binary files /dev/null and b/target/classes/com/oppo/push/controller/PushController.class differ diff --git a/target/classes/com/oppo/push/service/OppoPushService.class b/target/classes/com/oppo/push/service/OppoPushService.class new file mode 100644 index 0000000..71b37cc Binary files /dev/null and b/target/classes/com/oppo/push/service/OppoPushService.class differ diff --git a/test-request.json b/test-request.json new file mode 100644 index 0000000..12a2419 --- /dev/null +++ b/test-request.json @@ -0,0 +1,7 @@ +{ + "targetValue": "your_registration_id_here", + "title": "测试私信消息", + "content": "这是一条通讯与服务(原私信)类消息的测试内容", + "messageType": "1" +} + diff --git a/调测使用说明.txt b/调测使用说明.txt new file mode 100644 index 0000000..f638da2 --- /dev/null +++ b/调测使用说明.txt @@ -0,0 +1,388 @@ +================================================================================ + OPPO推送服务 - 调测使用说明 +================================================================================ + +一、环境准备 +================================================================================ + +1. 系统要求 + - JDK 1.8 或更高版本 + - Maven 3.6 或更高版本 + - Windows/Linux/Mac 操作系统 + +2. 验证环境 + - 打开命令行,执行:java -version + - 打开命令行,执行:mvn -version + - 确保两个命令都能正常显示版本信息 + +3. 项目文件检查 + 确保以下文件存在: + - pom.xml(Maven配置文件) + - opush-server-sdk-1.1.0.jar(OPPO推送SDK) + - src/main/resources/application.properties(配置文件) + - src/main/java/com/oppo/push/(源代码目录) + + +二、配置说明 +================================================================================ + +1. 配置文件位置 + src/main/resources/application.properties + +2. 已配置的参数 + - AppKey: bb0819c889ae40cd8bde5a8ad4e670fe + - AppSecret: 9b5a0e6d560e406dbb70fbb4e0e38098 + - MasterSecret: 9b5a0e6d560e406dbb70fbb4e0e38098(默认与AppSecret相同) + - 频道ID: previte_message + - 频道名称: 消息推送 + - 服务端口: 8080 + +3. 配置修改(如需要) + 如果您的MasterSecret与AppSecret不同,请修改配置文件中的: + oppo.push.masterSecret=您的实际MasterSecret值 + + +三、启动服务 +================================================================================ + +方式一:使用Maven直接运行(推荐) +---------------------------------------- +1. 打开命令行(CMD或PowerShell) +2. 进入项目目录:cd d:\oppo_push_server +3. 执行启动命令:mvn spring-boot:run +4. 等待启动完成,看到以下信息表示启动成功: + ======================================== + OPPO推送服务已启动 + API地址: http://localhost:8080/api/push + 健康检查: http://localhost:8080/api/push/health + ======================================== + +方式二:打包后运行 +---------------------------------------- +1. 打包项目:mvn clean package +2. 运行jar包:java -jar target/oppo-push-server-1.0.0.jar +3. 启动成功后同上 + + +四、API接口说明 +================================================================================ + +1. 健康检查接口 + - 请求方式:GET + - 请求地址:http://localhost:8080/api/push/health + - 功能说明:检查服务是否正常运行 + - 返回示例: + { + "status": "ok", + "service": "OPPO Push Server" + } + +2. 获取Access Token接口 + - 请求方式:GET + - 请求地址:http://localhost:8080/api/push/token + - 功能说明:获取OPPO推送服务的访问令牌 + - 返回示例(成功): + { + "success": true, + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + } + - 返回示例(失败): + { + "success": false, + "message": "获取Access Token失败: 错误信息" + } + +3. 发送通讯与服务(原私信)类消息接口 + - 请求方式:POST + - 请求地址:http://localhost:8080/api/push/send + - 请求头:Content-Type: application/json + - 请求体(JSON格式): + { + "targetValue": "设备的registration_id或alias", + "title": "消息标题", + "content": "消息内容", + "messageType": "1" + } + - 参数说明: + * targetValue(必填):目标设备的标识 + - 可以是registration_id(设备注册ID) + - 可以是alias(别名) + - 可以是tag(标签) + * title(必填):消息标题 + * content(必填):消息内容 + * messageType(可选):消息类型 + - "1":通知栏消息(默认) + - "2":透传消息 + - 返回示例(成功): + { + "success": true, + "code": 0, + "message": "success", + "data": { + "messageId": "xxx", + "taskId": "xxx" + } + } + - 返回示例(失败): + { + "success": false, + "code": 1001, + "message": "错误信息", + "data": null + } + + +五、测试步骤 +================================================================================ + +步骤1:启动服务 +---------------------------------------- +执行:mvn spring-boot:run +等待服务启动完成 + +步骤2:健康检查 +---------------------------------------- +打开浏览器访问:http://localhost:8080/api/push/health +或使用curl命令: + curl http://localhost:8080/api/push/health + +预期结果:返回 {"status":"ok","service":"OPPO Push Server"} + +步骤3:获取Token(测试认证) +---------------------------------------- +使用curl命令: + curl http://localhost:8080/api/push/token + +或使用浏览器访问:http://localhost:8080/api/push/token + +预期结果:返回包含token的JSON,success为true + +步骤4:准备测试数据 +---------------------------------------- +1. 获取目标设备的registration_id + - 在您的移动应用中集成OPPO推送SDK + - 应用启动后,SDK会返回registration_id + - 记录下这个registration_id用于测试 + +2. 修改test-request.json文件 + 将文件中的 "your_registration_id_here" 替换为实际的registration_id + +步骤5:发送测试消息 +---------------------------------------- +使用curl命令(Windows PowerShell): + curl -X POST http://localhost:8080/api/push/send ` + -H "Content-Type: application/json" ` + -d @test-request.json + +使用curl命令(Linux/Mac): + curl -X POST http://localhost:8080/api/push/send \ + -H "Content-Type: application/json" \ + -d @test-request.json + +或使用Postman: + 1. 创建POST请求 + 2. URL: http://localhost:8080/api/push/send + 3. Headers: Content-Type = application/json + 4. Body选择raw,格式选择JSON + 5. 输入以下内容: + { + "targetValue": "您的registration_id", + "title": "测试私信消息", + "content": "这是一条通讯与服务(原私信)类消息的测试内容", + "messageType": "1" + } + 6. 点击Send发送 + +预期结果: + - 返回success为true + - 移动设备收到推送通知 + - 通知显示在"消息推送"频道中 + + +六、使用Postman测试(推荐) +================================================================================ + +1. 导入请求集合 + - 打开Postman + - 创建新的Collection:OPPO推送测试 + - 添加以下三个请求: + +2. 健康检查请求 + - 方法:GET + - URL:http://localhost:8080/api/push/health + - 点击Send,应该返回成功状态 + +3. 获取Token请求 + - 方法:GET + - URL:http://localhost:8080/api/push/token + - 点击Send,应该返回token + +4. 发送消息请求 + - 方法:POST + - URL:http://localhost:8080/api/push/send + - Headers: + Key: Content-Type + Value: application/json + - Body(选择raw,格式JSON): + { + "targetValue": "替换为实际的registration_id", + "title": "测试标题", + "content": "测试内容", + "messageType": "1" + } + - 点击Send发送 + + +七、常见问题排查 +================================================================================ + +问题1:服务启动失败 +---------------------------------------- +可能原因: + - 端口8080被占用 + - JDK版本不兼容 + - Maven依赖下载失败 + +解决方法: + 1. 检查端口占用:netstat -ano | findstr :8080 + 2. 修改端口:在application.properties中修改server.port=8081 + 3. 检查JDK版本:java -version(需要1.8+) + 4. 清理Maven缓存:mvn clean + +问题2:获取Token失败 +---------------------------------------- +可能原因: + - AppKey或MasterSecret配置错误 + - 网络连接问题 + - OPPO服务端异常 + +解决方法: + 1. 检查配置文件中的AppKey和MasterSecret是否正确 + 2. 检查网络连接是否正常 + 3. 查看控制台日志,确认具体错误信息 + 4. 确认在OPPO开放平台已开通推送服务 + +问题3:发送消息失败 +---------------------------------------- +可能原因: + - Token过期或无效 + - targetValue(registration_id)无效 + - 消息格式错误 + - 设备未在线 + +解决方法: + 1. 重新获取Token:访问 /api/push/token 接口 + 2. 确认registration_id是否正确 + 3. 检查请求体JSON格式是否正确 + 4. 确认目标设备已连接网络且应用在运行 + 5. 查看控制台日志获取详细错误信息 + +问题4:设备收不到推送 +---------------------------------------- +可能原因: + - 设备未正确集成OPPO推送SDK + - 应用未获得通知权限 + - 设备网络问题 + - 频道配置不正确 + +解决方法: + 1. 确认移动应用已正确集成OPPO推送SDK + 2. 检查应用的通知权限是否开启 + 3. 确认设备网络连接正常 + 4. 检查频道ID配置是否为"previte_message" + 5. 在OPPO开放平台查看推送统计,确认消息是否已发送 + +问题5:编译错误 +---------------------------------------- +可能原因: + - 缺少依赖 + - 代码语法错误 + +解决方法: + 1. 执行:mvn clean install + 2. 检查IDE是否显示错误 + 3. 确认opush-server-sdk-1.1.0.jar文件存在 + + +八、日志查看 +================================================================================ + +1. 控制台日志 + 服务启动后,所有日志会输出到控制台,包括: + - 服务启动信息 + - Token获取日志 + - 消息发送日志 + - 错误信息 + +2. 关键日志信息 + - "获取Access Token成功":表示认证成功 + - "发送消息结果":显示消息发送的详细结果 + - "获取Access Token失败":表示认证失败,需要检查配置 + - "发送消息异常":表示发送失败,查看具体错误信息 + + +九、调试技巧 +================================================================================ + +1. 使用健康检查接口确认服务正常运行 + +2. 先测试获取Token,确认认证配置正确 + +3. 使用Postman等工具可以更方便地测试和查看响应 + +4. 查看控制台日志,了解详细的执行过程 + +5. 如果发送失败,先检查: + - Token是否有效 + - registration_id是否正确 + - 请求格式是否正确 + +6. 建议测试流程: + 健康检查 → 获取Token → 发送消息 + + +十、注意事项 +================================================================================ + +1. Token会自动缓存,有效期约24小时,无需频繁获取 + +2. 确保在OPPO开放平台已正确配置应用信息 + +3. registration_id需要从移动应用端获取,不能随意填写 + +4. 通讯与服务类消息会自动使用配置的频道ID(previte_message) + +5. 测试时建议使用真实的设备registration_id + +6. 如果MasterSecret与AppSecret不同,务必更新配置文件 + +7. 生产环境建议将敏感信息(AppKey、Secret等)配置为环境变量 + +8. 通讯与服务类消息说明: + - 根据OPPO官方文档(https://open.oppomobile.com/documentation/page/info?id=13189) + - 必须设置 channel_id 为 "previte_message" + - 必须设置 channel_name 为 "消息推送" + - 这些参数已在代码中自动配置,无需手动设置 + - 消息会显示在OPPO手机的"消息推送"频道中 + + +十一、技术支持 +================================================================================ + +1. OPPO推送服务文档 + - 通讯与服务类消息文档:https://open.oppomobile.com/documentation/page/info?id=13189 + - 推送服务总文档:https://open.oppomobile.com/documentation/page/info?id=11233 + +2. 查看项目文档 + - README.md:项目总体说明 + - 通讯与服务类消息说明.md:通讯与服务类消息详细说明 + +3. 查看控制台日志获取详细错误信息 + +4. 检查OPPO开放平台的推送统计,确认消息发送状态 + + +================================================================================ + 祝您测试顺利! +================================================================================ + diff --git a/通讯与服务类消息说明.md b/通讯与服务类消息说明.md new file mode 100644 index 0000000..c91fd06 --- /dev/null +++ b/通讯与服务类消息说明.md @@ -0,0 +1,136 @@ +# 通讯与服务类消息发送说明 + +## 概述 + +本文档说明如何使用本后台服务发送**通讯与服务(原私信)类消息**。 + +根据 [OPPO推送服务官方文档](https://open.oppomobile.com/documentation/page/info?id=13189),通讯与服务类消息需要特殊的参数配置。 + +## 关键配置参数 + +### 1. 频道ID(channel_id) +- **值**: `previte_message` +- **位置**: `src/main/resources/application.properties` +- **配置项**: `oppo.push.channel.id.im=previte_message` + +### 2. 频道名称(channel_name) +- **值**: `消息推送` +- **位置**: `src/main/resources/application.properties` +- **配置项**: `oppo.push.channel.name.im=消息推送` + +## 代码实现 + +在 `OppoPushService.java` 中,发送消息时会自动设置以下参数: + +```java +// 通讯与服务(原私信)类消息特殊参数 +notification.put("channel_id", config.getChannelIdIm()); // previte_message +notification.put("channel_name", config.getChannelNameIm()); // 消息推送 + +// extra参数(可选) +Map extra = new HashMap<>(); +extra.put("message_type", "chat"); // 标识为私信类消息 +notification.put("extra", extra); +``` + +## 消息体结构 + +发送通讯与服务类消息时,完整的消息体结构如下: + +```json +{ + "target_type": 1, + "target_value": "设备的registration_id", + "notification": { + "title": "消息标题", + "content": "消息内容", + "click_action_type": 1, + "click_action_type_value": "", + "channel_id": "previte_message", + "channel_name": "消息推送", + "extra": { + "message_type": "chat" + } + } +} +``` + +## 测试步骤 + +### 1. 确保配置正确 + +检查 `application.properties` 文件: +```properties +oppo.push.channel.id.im=previte_message +oppo.push.channel.name.im=消息推送 +``` + +### 2. 启动服务 + +```bash +mvn spring-boot:run +``` + +### 3. 发送测试消息 + +使用 curl 命令: +```bash +curl -X POST http://localhost:8080/api/push/send \ + -H "Content-Type: application/json" \ + -d '{ + "targetValue": "您的registration_id", + "title": "测试私信", + "content": "这是一条通讯与服务类消息", + "messageType": "1" + }' +``` + +### 4. 验证结果 + +- 检查API返回:`success` 应为 `true` +- 检查设备:消息应出现在OPPO手机的"消息推送"频道中 +- 检查日志:查看控制台输出的详细日志 + +## 注意事项 + +1. **频道ID必须正确**:`channel_id` 必须设置为 `previte_message`,否则消息不会被识别为普通通知 + +2. **频道名称**:`channel_name` 设置为 `消息推送`,这是OPPO系统识别的标准名称 + +3. **设备端配置**:确保移动应用已正确集成OPPO推送SDK,并且应用已获得通知权限 + +4. **registration_id**:必须使用真实的设备registration_id,不能随意填写 + +5. **消息分类**:通过设置 `channel_id` 为 `previte_message`,消息会被OPPO系统自动分类为"通讯与服务"类消息 + +## 常见问题 + +### Q1: 消息发送成功但设备收不到? +**A**: 检查以下几点: +- 设备是否在线 +- 应用是否已获得通知权限 +- registration_id是否正确 +- 应用是否已正确集成OPPO推送SDK + +### Q2: 消息收到了但不是通讯与服务类? +**A**: 检查: +- `channel_id` 是否正确设置为 `previte_message` +- 查看日志确认消息体中的参数是否正确 + +### Q3: 如何确认消息类型? +**A**: +- 在OPPO手机上,通讯与服务类消息会显示在"消息推送"频道中 +- 可以通过OPPO开放平台的推送统计查看消息分类 + +## 相关文档 + +- [OPPO推送服务文档 - 通讯与服务类消息](https://open.oppomobile.com/documentation/page/info?id=13189) +- [OPPO开放平台](https://open.oppomobile.com) + +## 技术支持 + +如有问题,请: +1. 查看控制台日志获取详细错误信息 +2. 检查OPPO开放平台的推送统计 +3. 参考OPPO官方文档 +