介绍
UniPush
是个推(Getui)推出的一项推送服务。它是一个多平台推送解决方案
,旨在帮助开发者统一管理
和发送推送通知
,无论用户使用的是
Android、iOS 还是其他平台的设备。
主要特点和功能
多平台支持:UniPush 支持 Android、iOS
等主流平台,开发者只需要集成一次 SDK,就能实现跨平台的消息推送。
高送达率:个推的推送服务以高送达率著称,通过精准的推送通道和智能的推送策略,确保消息能够及时送达用户设备。
精准推送:支持根据用户标签、地理位置、行为等信息进行精准推送,提高消息的有效性和转化率。
实时统计:提供详尽的推送统计报告,开发者可以实时查看推送的送达率、点击率等数据,优化推送策略。
丰富的消息类型:支持文本消息、富媒体消息(图片、音频、视频)等多种形式的消息推送,满足不同应用场景的需求。
开发者友好:提供简单易用的 API 和
SDK,快速集成到应用中。同时,个推提供详细的文档和技术支持,帮助开发者解决集成过程中的问题。
多种推送策略:包括定时推送、地理围栏推送、用户分群推送等,开发者可以根据业务需求灵活选择合适的推送策略。
使用场景
营销推广:通过 UniPush
向用户发送促销、活动等通知,增加用户的活跃度和参与度。
系统通知:实时向用户推送重要的系统通知,如安全警告、账户变更等信息。
用户唤醒:向长时间未使用应用的用户发送提醒,唤醒用户再次使用应用
集成
个推SDK的主要目标是提升开发者在服务端集成个推推送服务的开发效率,满足调用过程中所需的鉴权、组装参数、发送HTTP请求等非功能性要求
下面的例子:集成个推SDK
,通过定时任务
或
手动调用
,查询数据库中待推送的消息,并使用个推平台将消息推送到特定用户的设备上。推送成功后,会更新消息的状态,以防重复推送
依赖
1 2 3 4 5
| <dependency> <groupId>com.getui.push</groupId> <artifactId>restful-sdk</artifactId> <version>1.0.0.4</version> </dependency>
|
yaml配置
1 2 3 4 5 6
| push: base_url: https://restapi.getui.com/v2/your_app_id (此处可以省略) app_id: your_app_id app_key: your_app_key app_secret: your_app_secret (此处可以省略) master_secret: your_master_secret
|
表
T_Sys_Message
表
1 2 3 4 5 6 7 8 9 10
| CREATE TABLE T_Sys_Message ( F_MessageID INT PRIMARY KEY AUTO_INCREMENT, F_Title VARCHAR(255), F_Summary TEXT, F_LinkUrl VARCHAR(255), F_IsPush TINYINT(1) DEFAULT 0, F_Status TINYINT(1) DEFAULT 0, F_RecieverUserID INT, F_IsDeleted TINYINT(1) DEFAULT 0 );
|
T_Sys_User
表
1 2 3 4 5 6 7 8 9
| CREATE TABLE T_Sys_User ( F_UserID INT PRIMARY KEY AUTO_INCREMENT, F_ClientID VARCHAR(255), F_FullName VARCHAR(255), F_IsDeleted TINYINT(1) DEFAULT 0, F_AccountState TINYINT(1) DEFAULT 1, F_LockState TINYINT(1) DEFAULT 0, F_UserState TINYINT(1) DEFAULT 1 );
|
外键约束
在 T_Sys_Message
表中,F_RecieverUserID
是一个外键,指向 T_Sys_User
表的 F_UserID
字段
1 2 3 4
| ALTER TABLE T_Sys_Message ADD CONSTRAINT fk_reciever_user FOREIGN KEY (F_RecieverUserID) REFERENCES T_Sys_User(F_UserID);
|
相关类
个推配置类
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
| @Configuration public class GTPushConfig { @Value("${push.app_id}") private String appId;
@Value("${push.app_key}") private String appKey;
@Value("${push.master_secret}") private String masterSecret;
@Bean(name = "myApiHelper") public ApiHelper apiHelper() { System.setProperty("http.maxConnections", "200");
GtApiConfiguration apiConfiguration = new GtApiConfiguration(); apiConfiguration.setAppId(appId); apiConfiguration.setAppKey(appKey); apiConfiguration.setMasterSecret(masterSecret); apiConfiguration.setDomain("https://restapi.getui.com/v2/"); ApiHelper apiHelper = ApiHelper.build(apiConfiguration); return apiHelper; } }
|
controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @RestController @RequestMapping("/sys-message") public class SysMessageController {
@Autowired private SysMessageService sysMessageService;
@NoAuthentication @RequestMapping(value = "/pushMess", method = RequestMethod.GET) public void forwardNews(){ sysMessageService.forwardNews(); } }
|
service
1 2 3 4
| public interface SysMessageService extends IService<SysMessage> {
void forwardNews(); }
|
serviceImpl
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
| @Slf4j @Service public class SysMessageServiceImpl extends ServiceBaseImpl<SysMessageMapper, SysMessage> implements SysMessageService {
@Resource private GeTuiUtils geTuiUtils;
@Autowired private SysMessageMapper sysMessageMapper;
@Override @Scheduled(cron = "0 0/2 * * * ?") public void forwardNews(){ List<Map<String, Object>> maps = sysMessageMapper.selectMessages(); if (maps.size() > 0) { maps.forEach(map -> { log.info("正在推送:{}", map); String cid = (String) map.get("F_ClientID"); String title = (String) map.get("F_Title"); String content = (String) map.get("F_Summary"); String linkUrl = (String) map.get("F_LinkUrl"); String type = GeTuiUtils.MESSAGE_PUSH; ApiResult<Map<String, Map<String, String>>> mapApiResult = geTuiUtils.pushToSingleByCid(cid, title, content, linkUrl, type); map.put("F_IsPush", 1); SysMessage sysMessage = null; try { sysMessage = this.mapToEntity(map, SysMessage.class, Other); } catch (IllegalAccessException | InstantiationException e) { e.printStackTrace(); } if (mapApiResult.isSuccess()) { sysMessageMapper.updateById(sysMessage); log.info("成功推送至:{}", map.get("F_FullName")); } else { log.error("无法推送消息至:{},请检查后重试", map.get("F_FullName")); }
}); } else { log.info("没有消息需要推送"); } } }
|
mapper
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
| @Mapper public interface SysMessageMapper extends MapperBase<SysMessage> {
@Select("SELECT\n" + "\tm.F_MessageID,\n" + "\tm.F_Title,\n" + "\tm.F_Summary,\n" + "\tm.F_LinkUrl,\n" + "\tm.F_IsPush,\n" + "\tm.F_Status,\n" + "\tu.F_ClientID,\n" + "\tu.F_FullName \n" + "FROM\n" + "\tT_Sys_Message m\n" + "\tLEFT JOIN T_Sys_User u ON m.F_RecieverUserID= u.F_UserID \n" + "WHERE\n" + "\tm.F_IsPush= 0 \n" + "\tAND m.F_Status = 0\n" + "\tAND m.F_IsDeleted= 0 \n" + "\tAND u.F_ClientID IS NOT NULL\n" + "\tAND u.F_IsDeleted = 0\n" + "\tAND u.F_AccountState = 1\n" + "\tAND u.F_LockState != 3\n" + "\tAND u.F_UserState = 1") List<Map<String, Object>> selectMessages(); }
|
工具类
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
| @Slf4j @Component public class GeTuiUtils { public static final String MESSAGE_PUSH = "1"; public static final String OFFLINE_PUSH = "2";
@Resource(name = "myApiHelper") private ApiHelper myApiHelper;
public ApiResult<Map<String, Map<String, String>>> pushToSingleByCid(String cid, String title, String content, String linkUrl, String type) { PushDTO<Audience> pushDTO = this.buildPushDTO(title, content, linkUrl, type); Audience audience = new Audience(); pushDTO.setAudience(audience); audience.addCid(cid); PushApi pushApi = myApiHelper.creatApi(PushApi.class); ApiResult<Map<String, Map<String, String>>> apiResult = pushApi.pushToSingleByCid(pushDTO); if (apiResult.isSuccess()) { log.info("推送成功"); System.out.println(apiResult.getData()); } else { log.error("推送失败"); System.out.println("code:" + apiResult.getCode() + ", msg: " + apiResult.getMsg()); } return apiResult; }
private PushDTO<Audience> buildPushDTO(String title, String content, String linkUrl, String type) { PushDTO<Audience> pushDTO = new PushDTO<>(); pushDTO.setRequestId(System.currentTimeMillis() + ""); pushDTO.setGroupName("wxb-group");
Strategy strategy = new Strategy(); strategy.setDef(1); strategy.setSt(1); Settings settings = new Settings(); settings.setStrategy(strategy); pushDTO.setSettings(settings); settings.setTtl(3600000);
PushChannel pushChannel = new PushChannel();
Map<String, String> map = new HashMap<>(); map.put("title", title); map.put("content", content); map.put("linkUrl", linkUrl); map.put("type", type); String payload = JSONUtils.toJSONString(map);
Alert alert = new Alert(); alert.setTitle(title); alert.setBody(content); Aps aps = new Aps(); aps.setContentAvailable(0); aps.setSound("default"); aps.setAlert(alert); IosDTO iosDTO = new IosDTO(); iosDTO.setPayload(payload); iosDTO.setAps(aps); iosDTO.setType("notify"); pushChannel.setIos(iosDTO);
AndroidDTO androidDTO = new AndroidDTO(); pushDTO.setPushChannel(pushChannel); pushChannel.setAndroid(androidDTO); Ups ups = new Ups(); androidDTO.setUps(ups); ThirdNotification notification1 = new ThirdNotification(); ups.setNotification(notification1); notification1.setTitle(title); notification1.setBody(content); notification1.setClickType("intent");
notification1.setIntent("intent:#Intent;action=android.intent.action.oppopush;" + "launchFlags=0x14000000;" + "component=包名/io.dcloud.PandoraEntry;S.UP-OL-SU=true;" + "S.title=" + title + ";" + "S.content="+ content + ";" + "S.payload=" + payload + ";end");
PushMessage pushMessage = new PushMessage(); pushDTO.setPushMessage(pushMessage); Map<String, Object> mapTC = new HashMap<>(); mapTC.put("title", title); mapTC.put("content", content); mapTC.put("payload", map); String jsonTC = JSONUtils.toJSONString(mapTC); pushMessage.setTransmission(jsonTC); log.info("pushDTO:{}", pushDTO); return pushDTO; }
private PushDTO<Audience> offlinePushDTO(String title, String content, String linkUrl, String type) { PushDTO<Audience> pushDTO = new PushDTO<>(); pushDTO.setRequestId(System.currentTimeMillis() + ""); pushDTO.setGroupName("wxb-group");
Map<String, String> map = new HashMap<>(); map.put("title", title); map.put("content", content); map.put("linkUrl", linkUrl); map.put("type", type);
PushMessage pushMessage = new PushMessage(); pushDTO.setPushMessage(pushMessage); Map<String, Object> mapTC = new HashMap<>(); mapTC.put("title", title); mapTC.put("content", content); mapTC.put("payload", map); String jsonTC = JSONUtils.toJSONString(mapTC); System.err.println(jsonTC); pushMessage.setTransmission(jsonTC); log.info("pushDTO:{}", pushDTO);
return pushDTO; } }
|
更多文档
参考
uniapp官网文档
参考
uni-app 集成推送
参考
SpringBoot项目集成UniPush 推送服务