feat: add cmpp inbound gateway listener

This commit is contained in:
hectorzhao
2026-07-07 16:19:14 +08:00
parent ad3b86ba0a
commit cc628d0214
14 changed files with 631 additions and 17 deletions
+17 -4
View File
@@ -1,6 +1,6 @@
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { randomBytes, createHash } from 'node:crypto';
import { randomBytes, randomInt, createHash } from 'node:crypto';
import { PrismaService } from '../prisma/prisma.service';
export interface CreateSmsApplicationDto {
@@ -150,15 +150,17 @@ export class SmsConfigService {
return application;
}
createApplication(data: CreateSmsApplicationDto) {
async createApplication(data: CreateSmsApplicationDto) {
const secret = randomBytes(24).toString('hex');
const queuePriority = normalizeApplicationQueuePriority(data.queuePriority);
const cmppAccount = await this.generateCmppAccount();
return this.prisma.smsApplication.create({
data: {
tenantId: data.tenantId,
name: data.name,
scene: data.scene,
callbackUrl: data.callbackUrl,
cmppAccount,
secretHash: hashSecret(secret),
dailyLimit: data.dailyLimit,
customerUnitPrice: data.customerUnitPrice ?? 0,
@@ -345,8 +347,8 @@ export class SmsConfigService {
gatewayHost: channel?.gatewayHost ?? '',
gatewayPort: channel?.gatewayPort ?? 0,
enterpriseCode: channel?.enterpriseCode ?? application.tenant.code,
account: channel?.account ?? application.tenant.code,
passwordCipher: channel?.passwordCipher ?? application.secretHash,
account: application.cmppAccount,
passwordCipher: application.secretHash,
srcId: channel?.srcId ?? '',
maxConnections: channel?.config && typeof channel.config === 'object' && 'maxConnections' in channel.config ? Number(channel.config.maxConnections) : 1,
heartbeatSeconds: 30,
@@ -355,6 +357,17 @@ export class SmsConfigService {
};
}
private async generateCmppAccount() {
for (let attempt = 0; attempt < 20; attempt += 1) {
const cmppAccount = String(randomInt(100000, 1000000));
const exists = await this.prisma.smsApplication.findUnique({ where: { cmppAccount } });
if (!exists) {
return cmppAccount;
}
}
throw new BadRequestException('Unable to generate unique CMPP account');
}
async disconnectApplicationConnection(applicationId: string, connectionId: string, data: StatusChangeDto = { status: 'disconnected' }) {
const application = await this.prisma.smsApplication.findUnique({ where: { id: applicationId } });
if (!application) {