diff --git a/src/controllers/conciergeBot.controller.js b/src/controllers/conciergeBot.controller.js index ae1282f..8a1cf4e 100644 --- a/src/controllers/conciergeBot.controller.js +++ b/src/controllers/conciergeBot.controller.js @@ -65,11 +65,13 @@ function normalizeReceptionPayload(p) { }) : []; const audience = p.dripAudience === 'all_inbound' ? 'all_inbound' : 'matched'; + const welcomeCtas = normalizeWhatsAppCtas(p.welcomeCtas, { strict: true }); return { enabled: Boolean(p.enabled), allowNonRegistered: Boolean(p.allowNonRegistered), prefillText: String(p.prefillText != null ? p.prefillText : 'Hi').trim() || 'Hi', welcomeMessage: String(p.welcomeMessage != null ? p.welcomeMessage : ''), + welcomeCtas, unmatchedBadgePrompt: String(p.unmatchedBadgePrompt != null ? p.unmatchedBadgePrompt : ''), staffHandoffMessage: String(p.staffHandoffMessage != null ? p.staffHandoffMessage : ''), dripAudience: audience, @@ -1244,4 +1246,4 @@ module.exports = { syncEventKnowledge, syncFoodKnowledge, syncPlacesKnowledge, -}; \ No newline at end of file +}; diff --git a/src/models/ConciergeBot.js b/src/models/ConciergeBot.js index ec48827..b0a6467 100644 --- a/src/models/ConciergeBot.js +++ b/src/models/ConciergeBot.js @@ -110,6 +110,14 @@ const conciergeBotSchema = new mongoose.Schema( type: String, default: 'Hi {firstName}! Welcome to {eventName}.', }, + /** Up to 3 reply CTAs or one URL CTA, sent with the welcome inside the session window. */ + welcomeCtas: [ + { + type: { type: String, enum: ['reply', 'url'], required: true }, + label: { type: String, default: '', trim: true, maxlength: 20 }, + value: { type: String, default: '', trim: true, maxlength: 2000 }, + }, + ], unmatchedBadgePrompt: { type: String, default: diff --git a/src/routes/conciergeBot.routes.js b/src/routes/conciergeBot.routes.js index da40cac..fe316cb 100644 --- a/src/routes/conciergeBot.routes.js +++ b/src/routes/conciergeBot.routes.js @@ -106,6 +106,7 @@ const receptionSchema = Joi.object({ allowNonRegistered: Joi.boolean(), prefillText: Joi.string().allow(''), welcomeMessage: Joi.string().allow(''), + welcomeCtas: Joi.array().items(ctaItemSchema).max(3), unmatchedBadgePrompt: Joi.string().allow(''), staffHandoffMessage: Joi.string().allow(''), dripAudience: Joi.string().valid('matched', 'all_inbound'), diff --git a/src/utils/whatsappCtas.js b/src/utils/whatsappCtas.js index e2b9e77..ab1defa 100644 --- a/src/utils/whatsappCtas.js +++ b/src/utils/whatsappCtas.js @@ -7,7 +7,7 @@ * @returns {{ type: 'reply'|'url', label: string, value: string }[]} */ function isPlaceholderCtaUrl(value) { - return /\{engagementUrl\}|\{eventId\}|\{participantId\}/i.test(String(value || '')); + return /\{url\}|\{engagementUrl\}|\{eventId\}|\{participantId\}/i.test(String(value || '')); } function isHttpCtaUrl(value) { @@ -33,7 +33,7 @@ function normalizeWhatsAppCtas(raw, opts = {}) { if (type === 'url') { if (!isHttpCtaUrl(value) && !isPlaceholderCtaUrl(value)) { if (strict) { - throw new Error('URL buttons must start with http:// or https://, or use {engagementUrl}'); + throw new Error('URL buttons must start with http:// or https://, or use {Url}'); } continue; }