- 新增基于设备令牌的推送通知接口 - 添加推送测试服务,支持应用启动时自动测试 - 新增推送测试文档说明 - 更新 APNS 配置和日志记录 - 迁移至 apns2 库的 PushType 枚举 - 替换订阅密钥文件 - 添加项目规则文档
99 lines
3.5 KiB
TypeScript
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);
|
|
}
|
|
}
|
|
|
|
} |