@tiledesk/tiledesk-server
Version:
The Tiledesk server module
98 lines (88 loc) • 4.02 kB
JavaScript
var winston = require('../config/winston');
const Request = require('../models/request');
const phoneUtil = require('../utils/phoneUtil');
const VOICE_TWILIO_CHANNEL_NAMES = ['voice_twilio', 'voice-twilio'];
const VOICE_VXML_CHANNEL_NAMES = ['voice-vxml', 'voice-vxml-enghouse'];
const BATCH_SIZE = 100;
function getPhoneFromVoiceTwilioCreatedBy(createdBy) {
if (!createdBy || typeof createdBy !== 'string') return null;
if (createdBy.startsWith('voice-twilio-')) return createdBy.replace(/^voice-twilio-/, '');
if (createdBy.startsWith('voice_twilio-')) return createdBy.replace(/^voice_twilio-/, '');
return null;
}
async function updateManyWithNormalizedPhone(filter, getPhoneFromDoc) {
let matched = 0;
let modified = 0;
const cursor = Request.find(filter).select('_id attributes createdBy').lean().cursor();
let batch = [];
for await (const doc of cursor) {
const rawPhone = getPhoneFromDoc(doc);
if (rawPhone == null || String(rawPhone).trim() === '') continue;
matched++;
const normalized = phoneUtil.normalizePhone(rawPhone);
const value = normalized != null && normalized !== '' ? normalized : String(rawPhone).trim();
if (value === '') continue;
batch.push({
updateOne: {
filter: { _id: doc._id },
update: { $set: { 'contact.phone': value } }
}
});
if (batch.length >= BATCH_SIZE) {
const result = await Request.bulkWrite(batch);
modified += result.modifiedCount;
batch = [];
}
}
if (batch.length > 0) {
const result = await Request.bulkWrite(batch);
modified += result.modifiedCount;
}
return { matched, modified };
}
async function up() {
try {
// Voice Twilio (voice-twilio / voice_twilio: phone from createdBy as "voice-twilio-{phone}" or "voice_twilio-{phone}")
const voiceFilter = {
'channel.name': { $in: VOICE_TWILIO_CHANNEL_NAMES },
createdBy: { $regex: /^(voice-twilio-|voice_twilio-)/ }
};
winston.info(`[phone-channels-migration] Voice Twilio Starting...`);
const voiceResult = await updateManyWithNormalizedPhone(voiceFilter, (doc) =>
getPhoneFromVoiceTwilioCreatedBy(doc.createdBy)
);
winston.info(`[phone-channels-migration] Voice Twilio: matched ${voiceResult.matched}, modified ${voiceResult.modified}`);
// Voice VXML (voice-vxml / voice-vxml-enghouse: phone from attributes.caller_phone)
const voiceVxmlFilter = {
'channel.name': { $in: VOICE_VXML_CHANNEL_NAMES },
'attributes.caller_phone': { $exists: true, $nin: [null, ''] }
};
winston.info(`[phone-channels-migration] Voice VXML Starting...`);
const voiceVxmlResult = await updateManyWithNormalizedPhone(voiceVxmlFilter, (doc) => doc.attributes?.caller_phone);
winston.info(`[phone-channels-migration] Voice VXML: matched ${voiceVxmlResult.matched}, modified ${voiceVxmlResult.modified}`);
// WhatsApp
const wabFilter = {
'channel.name': 'whatsapp',
createdBy: { $regex: /^wab-/ }
};
winston.info(`[phone-channels-migration] WhatsApp Starting...`);
const wabResult = await updateManyWithNormalizedPhone(wabFilter, (doc) =>
doc.createdBy && doc.createdBy.startsWith('wab-') ? doc.createdBy.replace(/^wab-/, '') : null
);
winston.info(`[phone-channels-migration] WhatsApp: matched ${wabResult.matched}, modified ${wabResult.modified}`);
// SMS-Twilio
const smsFilter = {
'channel.name': 'sms-twilio',
createdBy: { $regex: /^sms-twilio-/ }
};
winston.info(`[phone-channels-migration] SMS-Twilio Starting...`);
const smsResult = await updateManyWithNormalizedPhone(smsFilter, (doc) =>
doc.createdBy && doc.createdBy.startsWith('sms-twilio-') ? doc.createdBy.replace(/^sms-twilio-/, '') : null
);
winston.info(`[phone-channels-migration] SMS-Twilio: matched ${smsResult.matched}, modified ${smsResult.modified}`);
} catch (err) {
winston.error('[phone-channels-migration] Error:', err);
throw err;
}
}
module.exports = { up };