Changes in sending actual SMS via resolve-template endpoint
This commit is contained in:
parent
1e9947f88c
commit
2f9f469be8
|
|
@ -18,7 +18,9 @@ const axios = require('axios');
|
|||
const MERCHANT_ID = () => process.env.MERCHANT_ID;
|
||||
|
||||
function normalizeScopeId(value) {
|
||||
return typeof value === 'string' ? value.trim() : '';
|
||||
if (typeof value === 'string') return value.trim();
|
||||
if (typeof value === 'number' && Number.isFinite(value)) return String(value);
|
||||
return '';
|
||||
}
|
||||
|
||||
function getCompanyId(req) {
|
||||
|
|
@ -102,6 +104,34 @@ async function findBusinessByApplicationId(merchantId, applicationId) {
|
|||
return brandMatches[0] || null;
|
||||
}
|
||||
|
||||
async function findBusinessByBrandName(merchantId, brandName) {
|
||||
const normalizedBrandName = normalizeText(brandName).toLowerCase();
|
||||
if (!normalizedBrandName) return null;
|
||||
|
||||
const businesses = await getIndex(merchantId);
|
||||
const brandMatches = businesses.filter((business) => normalizeText(business.brandName).toLowerCase() === normalizedBrandName);
|
||||
|
||||
if (brandMatches.length > 1) {
|
||||
throw createHttpError(
|
||||
409,
|
||||
'Multiple businesses matched the provided brand name',
|
||||
{
|
||||
code: 'AMBIGUOUS_BUSINESS_MATCH',
|
||||
details: {
|
||||
companyId: merchantId,
|
||||
brandName: normalizedBrandName,
|
||||
matchedBusinesses: brandMatches.map((business) => ({
|
||||
businessId: business.businessId,
|
||||
brandName: business.brandName,
|
||||
})),
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return brandMatches[0] || null;
|
||||
}
|
||||
|
||||
const PROVIDER_FIELDS = ['providerName', 'senderId', 'dltEntityId', 'authKey'];
|
||||
|
||||
function createHttpError(status, message, extra = {}) {
|
||||
|
|
@ -152,6 +182,54 @@ function normalizeProvider(provider = {}, fallbackUpdatedAt = null) {
|
|||
};
|
||||
}
|
||||
|
||||
function getShipmentPayload(body) {
|
||||
return body?.payload?.shipment && typeof body.payload.shipment === 'object'
|
||||
? body.payload.shipment
|
||||
: null;
|
||||
}
|
||||
|
||||
function getShipmentBrandName(body) {
|
||||
return normalizeText(body?.payload?.shipment?.bags?.[0]?.brand?.brand_name);
|
||||
}
|
||||
|
||||
function getShipmentEventKey(body) {
|
||||
return normalizeText(body?.payload?.shipment?.status);
|
||||
}
|
||||
|
||||
function getShipmentToNumber(body) {
|
||||
return normalizeText(body?.payload?.shipment?.user?.mobile);
|
||||
}
|
||||
|
||||
async function sendResolveTemplateWorkflow({ template, toNumber, sourcePayload }) {
|
||||
const workflowUrl = normalizeText(process.env.WORKFLOW_URL_RESOLVE_TEMPLATE);
|
||||
if (!workflowUrl) {
|
||||
throw createHttpError(500, 'WORKFLOW_URL_RESOLVE_TEMPLATE is not configured');
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
workflowUrl,
|
||||
{ template, toNumber, sourcePayload },
|
||||
{
|
||||
timeout: 30000,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
validateStatus: () => true,
|
||||
}
|
||||
);
|
||||
|
||||
if (response.status < 200 || response.status >= 300) {
|
||||
throw createHttpError(
|
||||
502,
|
||||
`Resolve-template workflow failed with status ${response.status}`,
|
||||
{ details: response.data }
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
statusCode: response.status,
|
||||
response: response.data,
|
||||
};
|
||||
}
|
||||
|
||||
function getProviderPatch(input) {
|
||||
if (!input || typeof input !== 'object') return null;
|
||||
|
||||
|
|
@ -418,16 +496,20 @@ router.post('/resolve-template', async (req, res) => {
|
|||
console.log('[ResolveTemplate] Incoming payload:', JSON.stringify(req.body, null, 2));
|
||||
|
||||
const companyId = getCompanyId(req);
|
||||
const applicationId = getApplicationId(req);
|
||||
const event = normalizeText(req.body?.event);
|
||||
const shipment = getShipmentPayload(req.body);
|
||||
const brandName = getShipmentBrandName(req.body);
|
||||
const event = getShipmentEventKey(req.body);
|
||||
const toNumber = getShipmentToNumber(req.body);
|
||||
|
||||
if (!companyId) return res.status(400).json({ error: 'companyId is required' });
|
||||
if (!applicationId) return res.status(400).json({ error: 'applicationId is required' });
|
||||
if (!event) return res.status(400).json({ error: 'event is required' });
|
||||
if (!shipment) return res.status(400).json({ error: 'payload.shipment is required' });
|
||||
if (!brandName) return res.status(400).json({ error: 'payload.shipment.bags[0].brand.brand_name is required' });
|
||||
if (!event) return res.status(400).json({ error: 'payload.shipment.status is required' });
|
||||
if (!toNumber) return res.status(400).json({ error: 'payload.shipment.user.mobile is required' });
|
||||
|
||||
const business = await findBusinessByApplicationId(companyId, applicationId);
|
||||
const business = await findBusinessByBrandName(companyId, brandName);
|
||||
if (!business) {
|
||||
return res.status(404).json({ error: 'Business not found for applicationId' });
|
||||
return res.status(404).json({ error: 'Business not found for brand name' });
|
||||
}
|
||||
|
||||
const eventSlug = slugify(event);
|
||||
|
|
@ -438,13 +520,22 @@ router.post('/resolve-template', async (req, res) => {
|
|||
return res.status(404).json({ error: 'Whitelisted template not found' });
|
||||
}
|
||||
|
||||
const workflowResult = await sendResolveTemplateWorkflow({
|
||||
template: tmpl.selectedTemplate,
|
||||
toNumber,
|
||||
sourcePayload: req.body,
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
companyId,
|
||||
applicationId,
|
||||
businessId: business.businessId,
|
||||
brandName,
|
||||
event: eventSlug,
|
||||
templateId: normalizeText(tmpl.templateId),
|
||||
template: tmpl.selectedTemplate,
|
||||
toNumber,
|
||||
workflowResult,
|
||||
});
|
||||
} catch (err) {
|
||||
sendRouteError(res, err);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user