feat(push): 新增设备推送和测试功能

- 新增基于设备令牌的推送通知接口
- 添加推送测试服务,支持应用启动时自动测试
- 新增推送测试文档说明
- 更新 APNS 配置和日志记录
- 迁移至 apns2 库的 PushType 枚举
- 替换订阅密钥文件
- 添加项目规则文档
This commit is contained in:
richarjiang
2025-10-15 19:09:51 +08:00
parent 38dd740c8c
commit cc83b84c80
20 changed files with 728 additions and 37 deletions

View File

@@ -77,9 +77,7 @@ export class ApnsProvider implements OnModuleInit, OnModuleDestroy {
keyId,
signingKey,
defaultTopic: bundleId,
host: environment === 'production' ? 'api.push.apple.com' : 'api.development.push.apple.com',
port: 443,
production: environment === 'production',
// production: environment === 'production',
};
}
@@ -88,6 +86,7 @@ export class ApnsProvider implements OnModuleInit, OnModuleDestroy {
*/
private async initializeClient(): Promise<void> {
try {
this.logger.log(`Initializing APNs Client config: ${JSON.stringify(this.config)}`);
this.client = new ApnsClient(this.config);
this.logger.log(`APNs Client initialized for ${this.config.production ? 'Production' : 'Sandbox'} environment`);
} catch (error) {
@@ -102,7 +101,7 @@ export class ApnsProvider implements OnModuleInit, OnModuleDestroy {
private setupErrorHandlers(): void {
// 监听特定错误
this.client.on(Errors.badDeviceToken, (err) => {
this.logger.error(`Bad device token: ${err.deviceToken}`, err.reason);
this.logger.error(`Bad device token: ${err}`, err.reason);
});
this.client.on(Errors.unregistered, (err) => {
@@ -129,12 +128,14 @@ export class ApnsProvider implements OnModuleInit, OnModuleDestroy {
};
try {
this.logger.debug(`Sending notification to ${deviceTokens.length} devices`);
for (const deviceToken of deviceTokens) {
try {
// 为每个设备令牌创建新的通知实例
const deviceNotification = this.createDeviceNotification(notification, deviceToken);
this.logger.log(`Sending notification to device this.client.send deviceNotification ${JSON.stringify(deviceNotification, null, 2)}`);
await this.client.send(deviceNotification);
results.sent.push(deviceToken);
} catch (error) {
@@ -332,7 +333,9 @@ export class ApnsProvider implements OnModuleInit, OnModuleDestroy {
*/
private createDeviceNotification(notification: Notification, deviceToken: string): Notification {
// 创建新的通知实例,使用相同的选项但不同的设备令牌
return new Notification(deviceToken, notification.options);
return new Notification(deviceToken, {
alert: notification.options.alert,
});
}
/**