feat: add HTTP API and complete client workflows
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { BadRequestException, Injectable, Logger, NotFoundException, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
||||
import { BadRequestException, forwardRef, Inject, Injectable, Logger, NotFoundException, OnModuleDestroy, OnModuleInit, Optional } from '@nestjs/common';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { Queue, Worker } from 'bullmq';
|
||||
import IORedis from 'ioredis';
|
||||
@@ -9,6 +9,7 @@ import { setTimeout as sleep } from 'node:timers/promises';
|
||||
import { BillingService } from '../billing/billing.service';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { RiskReviewService } from '../risk-review/risk-review.service';
|
||||
import { OpenApiService } from '../open-api/open-api.service';
|
||||
|
||||
export interface CreateBatchTaskDto {
|
||||
tenantId: string;
|
||||
@@ -24,6 +25,7 @@ export interface CreateBatchTaskDto {
|
||||
sourceIp?: string;
|
||||
userAgent?: string;
|
||||
sourceType?: 'client' | 'api' | 'cmpp';
|
||||
clientMessageId?: string;
|
||||
}
|
||||
|
||||
export interface GatewayInboundAuthDto {
|
||||
@@ -258,6 +260,7 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly billing: BillingService,
|
||||
private readonly riskReview: RiskReviewService,
|
||||
@Optional() @Inject(forwardRef(() => OpenApiService)) private readonly openApi?: OpenApiService,
|
||||
) {}
|
||||
|
||||
onModuleInit() {
|
||||
@@ -379,6 +382,7 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
|
||||
signatureId: messageClassification.signatureId,
|
||||
drainageInfoId: messageClassification.drainageInfoId,
|
||||
messageId: `MSG-${randomUUID()}`,
|
||||
clientMessageId: data.clientMessageId,
|
||||
phoneNumber: phone,
|
||||
content: data.content,
|
||||
billingUnits: billing.billingUnitsPerMessage,
|
||||
@@ -965,6 +969,7 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
|
||||
destId: data.destId,
|
||||
content: data.content,
|
||||
receivedAt: record.receivedAt.toISOString(),
|
||||
uplinkMessageId: record.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1571,8 +1576,27 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
|
||||
}
|
||||
const application = await this.prisma.smsApplication.findUnique({
|
||||
where: { id: data.applicationId },
|
||||
select: { cmppAccount: true, downstreamReceiptRetryEnabled: true, downstreamUplinkRetryEnabled: true },
|
||||
select: { cmppAccount: true, downstreamReceiptRetryEnabled: true, downstreamUplinkRetryEnabled: true, httpConfig: true },
|
||||
});
|
||||
try {
|
||||
await this.openApi?.queueWebhookEvent({
|
||||
tenantId: data.tenantId,
|
||||
applicationId: data.applicationId,
|
||||
messageRecordId: data.messageRecordId,
|
||||
messageId: data.messageId,
|
||||
uplinkMessageId: typeof data.payload.uplinkMessageId === 'string' ? data.payload.uplinkMessageId : undefined,
|
||||
eventType: data.deliveryType,
|
||||
payload: data.payload,
|
||||
});
|
||||
} catch (error) {
|
||||
this.logger.error(`HTTP webhook queue failed for ${data.deliveryType}/${data.messageId ?? '-'}: ${error instanceof Error ? error.message : String(error)}`);
|
||||
}
|
||||
const deliveryMode = data.deliveryType === 'receipt'
|
||||
? application?.httpConfig?.receiptDeliveryMode ?? 'cmpp'
|
||||
: application?.httpConfig?.uplinkDeliveryMode ?? 'cmpp';
|
||||
if (!['cmpp', 'both'].includes(deliveryMode)) {
|
||||
return null;
|
||||
}
|
||||
const payload = { account: application?.cmppAccount, applicationId: data.applicationId, ...data.payload };
|
||||
const delivery = await this.prisma.cmppDownstreamDelivery.create({
|
||||
data: {
|
||||
|
||||
Reference in New Issue
Block a user