想必大家在进行uniapp推送时走了不少弯路吧?要么收不到,要么没有回调,本文自己用node写了一个推送服务,最主要的还是还是数据格式方面,按照我下面的这份代码100%是可以收到通知的。
// 个推推送,2022-06-17
import { Service, Context } from 'egg';
import crypto = require('crypto');
interface ToListConfig {
cid: any[];
title: string;
content: string;
payload?: any;
}
export default class Getui extends Service {
baseUrl: string;
constructor(ctx: Context) {
super(ctx);
const { AppID } = this.config.getui;
this.baseUrl = `https://restapi.getui.com/v2/${AppID}`;
}
/**
* 获取个推token
*/
private async getGetuiToken(): Promise<{ expire_time: string, token: string }> {
const redisTokenData: any = await this.app.redis.get('getuiToken');
const { AppKey, MasterSecret } = this.config.getui;
const url = `${this.baseUrl}/auth`;
const hash = crypto.createHash('sha256');
const timestamp = new Date().getTime();
const sign = hash.update(AppKey + timestamp + MasterSecret).digest('hex');
const params = {
sign,
timestamp,
appkey: AppKey,
};
if (redisTokenData) {
const parseData = JSON.parse(redisTokenData);
if (Number(parseData.expire_time) >= timestamp) {
console.log('redis token 有效', parseData);
return parseData;
}
}
const { data }: any = await this.ctx.curl(url, {
dataType: 'json',
method: 'POST',
headers: {
'content-type': 'application/json;charset=utf-8',
},
data: params,
});
// 存redis
await this.app.redis.set('getuiToken', JSON.stringify(data.data));
console.log('getui token', data);
return data.data;
}
/**
* 个推创建消息体
* @param { String } title 标题
* @param { String } body 内容
* @param { Object } payload 自定义数据
*/
private async ceateMessage(title:string, body: string, payload: any): Promise<{ taskid: string }> {
const url = `${this.baseUrl}/push/list/message`;
const customData = { title, body, ...payload };
const { token } = await this.getGetuiToken();
const { data } = await this.ctx.curl(url, {
dataType: 'json',
method: 'POST',
headers: {
'content-type': 'application/json;charset=utf-8',
token,
},
data: {
request_id: new Date().getTime(),
settings: {
ttl: 3600000,
strategy: {
default: 4,
},
},
push_message: {
// 透传消息格式:{"title": "xxx","content": "xxx","payload": "xxx"}
transmission: JSON.stringify({
title,
content: body,
payload: customData,
}),
},
push_channel: {
android: {
ups: {
notification: {
title,
body,
click_type: 'intent',
intent: `intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;component=com.xxx.xxx/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=${title};S.content=${body};S.payload=${JSON.stringify(customData)};end`,
},
},
},
ios: {
type: 'notify',
payload: JSON.stringify(customData),
aps: {
alert: {
title,
body,
},
'content-available': 0,
},
},
},
},
});
return data.data;
}
/**
* app个推推送测试
* @param { Object } params 参数对象
* @param { Array } params.cid 数组clientid
* @param { String } params.title 标题
* @param { String } params.content 内容
* @param { Object } params.payload 自定义数据
*/
public async toList(params: ToListConfig) {
const { cid, title, content, payload } = params;
const { token, expire_time } = await this.getGetuiToken();
const { taskid } = await this.ceateMessage(title, content, payload);
const { data } = await this.ctx.curl(`${this.baseUrl}/push/list/cid`, {
dataType: 'json',
method: 'POST',
headers: {
'content-type': 'application/json;charset=utf-8',
token,
},
data: {
taskid,
audience: {
cid,
},
},
});
if (data.code !== 0) {
throw { data, msg: '发送失败' };
}
console.log('发送成功', data);
return {
...data,
expire_time: new Date(+expire_time).toLocaleString(),
token,
payload,
title,
content,
taskid,
};
}
}