@peopl-health/nexus 3.5.2 → 3.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -524,7 +524,7 @@ class TwilioProvider extends MessageProvider {
|
|
|
524
524
|
const wa = req.whatsapp;
|
|
525
525
|
approvalRequest = {
|
|
526
526
|
sid: req.sid,
|
|
527
|
-
status: (wa?.status || req.status
|
|
527
|
+
status: (wa?.status || req.status).toUpperCase(),
|
|
528
528
|
...(wa && { category: wa.category, name: wa.name, rejectionReason: wa.rejection_reason, contentType: wa.content_type }),
|
|
529
529
|
dateCreated: req.dateCreated || req.date_created,
|
|
530
530
|
dateUpdated: req.dateUpdated || req.date_updated
|
|
@@ -113,87 +113,86 @@ const createTemplate = async (req, res) => {
|
|
|
113
113
|
|
|
114
114
|
const listTemplates = async (req, res) => {
|
|
115
115
|
try {
|
|
116
|
-
const { status: queryStatus, type, limit = 50, showFlows: queryShowFlows } = req.query;
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
const showFlows = type === 'flow' || queryShowFlows === 'true';
|
|
121
|
-
const filteredTwilioTemplates = twilioRawTemplates.filter(template => {
|
|
122
|
-
const isFlow = template.types && template.types['twilio/flex'];
|
|
123
|
-
const statusMatch = queryStatus ? template.status === queryStatus : true;
|
|
124
|
-
return (showFlows || !isFlow) && statusMatch;
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
const validTwilioSids = filteredTwilioTemplates.map(t => t.sid);
|
|
128
|
-
|
|
129
|
-
await TemplateModel.deleteMany({ sid: { $nin: validTwilioSids } });
|
|
130
|
-
|
|
131
|
-
for (const twilioTemplate of filteredTwilioTemplates) {
|
|
132
|
-
const updateFields = {
|
|
133
|
-
friendlyName: twilioTemplate.friendlyName,
|
|
134
|
-
category: twilioTemplate.types?.['twilio/text']?.categories?.[0] || 'UTILITY',
|
|
135
|
-
language: twilioTemplate.language || 'es',
|
|
136
|
-
status: twilioTemplate.status || 'DRAFT',
|
|
137
|
-
lastUpdated: new Date(),
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
try {
|
|
141
|
-
const approvalInfo = await provider.checkApprovalStatus(twilioTemplate.sid);
|
|
142
|
-
if (approvalInfo && approvalInfo.approvalRequest) {
|
|
143
|
-
const reqData = approvalInfo.approvalRequest;
|
|
144
|
-
updateFields.approvalRequest = {
|
|
145
|
-
sid: reqData.sid,
|
|
146
|
-
status: reqData.status || 'PENDING',
|
|
147
|
-
dateSubmitted: reqData.dateCreated ? new Date(reqData.dateCreated) : new Date(),
|
|
148
|
-
dateUpdated: reqData.dateUpdated ? new Date(reqData.dateUpdated) : new Date(),
|
|
149
|
-
rejectionReason: reqData.rejectionReason || ''
|
|
150
|
-
};
|
|
151
|
-
if (reqData.status === 'APPROVED') updateFields.status = 'APPROVED';
|
|
152
|
-
else if (reqData.status === 'REJECTED') updateFields.status = 'REJECTED';
|
|
153
|
-
else if (reqData.status === 'PENDING') updateFields.status = 'PENDING';
|
|
154
|
-
}
|
|
155
|
-
} catch (err) {
|
|
156
|
-
logger.warn(`Could not fetch approval status for template ${twilioTemplate.sid}:`, err.message);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const onInsertFields = {
|
|
160
|
-
sid: twilioTemplate.sid,
|
|
161
|
-
name: (twilioTemplate.friendlyName || `template_${twilioTemplate.sid}`).replace(/[^a-zA-Z0-9_]/g, '_').toLowerCase(),
|
|
162
|
-
dateCreated: new Date(twilioTemplate.dateCreated),
|
|
163
|
-
body: '',
|
|
164
|
-
footer: '',
|
|
165
|
-
variables: [],
|
|
166
|
-
components: []
|
|
167
|
-
};
|
|
116
|
+
const { status: queryStatus, type, limit: queryLimit = 50, showFlows: queryShowFlows } = req.query;
|
|
117
|
+
const page = Math.max(parseInt(req.query.page) || 1, 1);
|
|
118
|
+
const limit = Math.min(Math.max(parseInt(queryLimit) || 50, 1), 100);
|
|
119
|
+
const skip = (page - 1) * limit;
|
|
168
120
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
{
|
|
172
|
-
$set: updateFields,
|
|
173
|
-
$setOnInsert: onInsertFields
|
|
174
|
-
},
|
|
175
|
-
{ upsert: true }
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const findCriteria = { sid: { $in: validTwilioSids } };
|
|
121
|
+
const findCriteria = {};
|
|
122
|
+
|
|
180
123
|
if (queryStatus) {
|
|
181
124
|
findCriteria.status = queryStatus;
|
|
182
125
|
}
|
|
126
|
+
|
|
127
|
+
const showFlows = type === 'flow' || queryShowFlows === 'true';
|
|
128
|
+
if (showFlows) {
|
|
129
|
+
findCriteria.type = 'twilio/flex';
|
|
130
|
+
} else {
|
|
131
|
+
findCriteria.type = { $ne: 'twilio/flex' };
|
|
132
|
+
}
|
|
183
133
|
|
|
184
|
-
|
|
134
|
+
const total = await TemplateModel.countDocuments(findCriteria);
|
|
135
|
+
const totalPages = Math.ceil(total / limit);
|
|
136
|
+
|
|
137
|
+
const templates = await TemplateModel.find(findCriteria)
|
|
185
138
|
.sort({ dateCreated: -1 })
|
|
186
|
-
.
|
|
139
|
+
.skip(skip)
|
|
140
|
+
.limit(limit)
|
|
187
141
|
.lean();
|
|
188
142
|
|
|
189
|
-
const
|
|
143
|
+
const provider = requireProvider();
|
|
144
|
+
|
|
145
|
+
const approvalPromises = templates
|
|
146
|
+
.filter(template => template.status !== 'APPROVED' && template.status !== 'REJECTED')
|
|
147
|
+
.map(async (template) => {
|
|
148
|
+
try {
|
|
149
|
+
const approvalInfo = await provider.checkApprovalStatus(template.sid);
|
|
150
|
+
if (approvalInfo && approvalInfo.approvalRequest) {
|
|
151
|
+
const reqData = approvalInfo.approvalRequest;
|
|
152
|
+
const updateFields = {
|
|
153
|
+
approvalRequest: {
|
|
154
|
+
sid: reqData.sid,
|
|
155
|
+
status: reqData.status,
|
|
156
|
+
dateSubmitted: reqData.dateCreated ? new Date(reqData.dateCreated) : new Date(),
|
|
157
|
+
dateUpdated: reqData.dateUpdated ? new Date(reqData.dateUpdated) : new Date(),
|
|
158
|
+
rejectionReason: reqData.rejectionReason || ''
|
|
159
|
+
},
|
|
160
|
+
lastUpdated: new Date(),
|
|
161
|
+
status: reqData.status
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
await TemplateModel.updateOne(
|
|
165
|
+
{ sid: template.sid },
|
|
166
|
+
{ $set: updateFields }
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
Object.assign(template, {
|
|
170
|
+
approvalRequest: updateFields.approvalRequest,
|
|
171
|
+
status: updateFields.status,
|
|
172
|
+
lastUpdated: updateFields.lastUpdated
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
} catch (err) {
|
|
176
|
+
logger.warn(`Could not fetch approval status for template ${template.sid}:`, err.message);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
await Promise.all(approvalPromises);
|
|
190
181
|
|
|
191
182
|
return res.status(200).json({
|
|
192
183
|
success: true,
|
|
193
|
-
templates:
|
|
194
|
-
count:
|
|
184
|
+
templates: templates.map(_formatTemplate),
|
|
185
|
+
count: templates.length,
|
|
186
|
+
pagination: {
|
|
187
|
+
page,
|
|
188
|
+
limit,
|
|
189
|
+
total,
|
|
190
|
+
totalPages,
|
|
191
|
+
hasNext: page < totalPages,
|
|
192
|
+
hasPrev: page > 1
|
|
193
|
+
}
|
|
195
194
|
});
|
|
196
|
-
|
|
195
|
+
|
|
197
196
|
} catch (error) {
|
|
198
197
|
logger.error('Error in listTemplates:', { error: error.message });
|
|
199
198
|
return handleApiError(res, error, 'Failed to list templates');
|
|
@@ -9,11 +9,12 @@ const TemplateSchema = new mongoose.Schema({
|
|
|
9
9
|
default: 'UTILITY',
|
|
10
10
|
enum: ['UTILITY', 'MARKETING', 'AUTHENTICATION']
|
|
11
11
|
},
|
|
12
|
+
type: String,
|
|
12
13
|
language: { type: String, default: 'es' },
|
|
13
14
|
status: {
|
|
14
15
|
type: String,
|
|
15
|
-
default: '
|
|
16
|
-
enum: ['
|
|
16
|
+
default: 'UNSUBMITTED',
|
|
17
|
+
enum: ['UNSUBMITTED', 'RECEIVED', 'PENDING', 'APPROVED', 'REJECTED', 'PAUSED', 'DISABLED']
|
|
17
18
|
},
|
|
18
19
|
body: String,
|
|
19
20
|
footer: String,
|