Files
plates-server/src/push-notifications/push-test.service.ts
richarjiang cc83b84c80 feat(push): 新增设备推送和测试功能
- 新增基于设备令牌的推送通知接口
- 添加推送测试服务,支持应用启动时自动测试
- 新增推送测试文档说明
- 更新 APNS 配置和日志记录
- 迁移至 apns2 库的 PushType 枚举
- 替换订阅密钥文件
- 添加项目规则文档
2025-10-15 19:09:51 +08:00

99 lines
3.5 KiB
TypeScript

import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PushNotificationsService } from './push-notifications.service';
import { PushTokenService } from './push-token.service';
import { UserPushToken } from './models/user-push-token.model';
import { InjectModel } from '@nestjs/sequelize';
import { Op } from 'sequelize';
import { PushType } from 'apns2';
@Injectable()
export class PushTestService implements OnModuleInit {
private readonly logger = new Logger(PushTestService.name);
constructor(
@InjectModel(UserPushToken)
private readonly pushTokenModel: typeof UserPushToken,
private readonly pushNotificationsService: PushNotificationsService,
private readonly pushTokenService: PushTokenService,
private readonly configService: ConfigService,
) { }
/**
* 模块初始化时执行
*/
async onModuleInit() {
// 检查是否启用推送测试
const enablePushTest = this.configService.get<boolean>('ENABLE_PUSH_TEST', false);
if (!enablePushTest) {
this.logger.log('Push test is disabled. Skipping...');
return;
}
// 延迟执行,确保应用完全启动
setTimeout(async () => {
try {
await this.performPushTest();
} catch (error) {
this.logger.error(`Push test failed: ${error.message}`, error);
}
}, 5000); // 5秒后执行
}
/**
* 执行推送测试
*/
private async performPushTest(): Promise<void> {
this.logger.log('Starting push test...');
try {
// 获取所有活跃的推送令牌
const activeTokens = await this.pushTokenModel.findAll({
where: {
isActive: true,
},
limit: 10, // 限制测试数量,避免发送过多推送
});
if (activeTokens.length === 0) {
this.logger.log('No active push tokens found for testing');
return;
}
this.logger.log(`Found ${activeTokens.length} active tokens for testing`);
// 准备测试推送内容
const testTitle = this.configService.get<string>('PUSH_TEST_TITLE', '测试推送');
const testBody = this.configService.get<string>('PUSH_TEST_BODY', '这是一条测试推送消息,用于验证推送功能是否正常工作。');
// 发送测试推送
const result = await this.pushNotificationsService.sendBatchNotificationToDevices({
deviceTokens: activeTokens.map(token => token.deviceToken),
title: testTitle,
body: testBody,
pushType: PushType.alert,
});
if (result.code === 0) {
this.logger.log(`Push test completed successfully. Sent: ${result.data.successCount}, Failed: ${result.data.failedCount}`);
} else {
this.logger.warn(`Push test completed with issues. Sent: ${result.data.successCount}, Failed: ${result.data.failedCount}`);
}
// 记录详细结果
if (result.data.results && result.data.results.length > 0) {
result.data.results.forEach((resultItem, index) => {
if (resultItem.success) {
this.logger.log(`Push test success for user ${resultItem.userId}, device ${resultItem.deviceToken.substring(0, 10)}...`);
} else {
this.logger.warn(`Push test failed for user ${resultItem.userId}, device ${resultItem.deviceToken.substring(0, 10)}...: ${resultItem.error}`);
}
});
}
} catch (error) {
this.logger.error(`Error during push test: ${error.message}`, error);
}
}
}