From f25f20ed63dcf7758ca483cdfea36b47b9b0f12b Mon Sep 17 00:00:00 2001 From: Arnas Donauskas Date: Fri, 17 Apr 2026 21:36:40 +0300 Subject: [PATCH] fix(automations): order send_template params numerically, not lexicographically MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Meta's template placeholders are positional ({{1}}, {{2}}, …). We previously sorted the keys of step_config.variables lexicographically, so a template with ≥10 variables got params in the order "1", "10", "2", …, silently scrambling every render past the 9th placeholder. Fix: sort numeric-looking keys by numeric value, fall back to locale compare for non-numeric keys. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/lib/automations/engine.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/lib/automations/engine.ts b/src/lib/automations/engine.ts index 1a131fa..43120ac 100644 --- a/src/lib/automations/engine.ts +++ b/src/lib/automations/engine.ts @@ -315,9 +315,22 @@ async function runStep(step: AutomationStep, args: ExecuteArgs): Promise if (!args.contactId) throw new Error('send_template needs a contact') if (!cfg.template_name) throw new Error('send_template needs template_name') const conversationId = await resolveConversationId(args) + // Meta templates use positional {{1}}, {{2}}, … placeholders, so + // we MUST emit params in strict numeric order. Lexicographic sort + // of "1", "2", …, "10" yields "1", "10", "2", … which silently + // scrambles every template with ≥10 variables. const params = cfg.variables ? Object.keys(cfg.variables) - .sort() + .sort((a, b) => { + const na = Number(a) + const nb = Number(b) + const aNum = Number.isFinite(na) + const bNum = Number.isFinite(nb) + if (aNum && bNum) return na - nb + if (aNum) return -1 + if (bNum) return 1 + return a.localeCompare(b) + }) .map((k) => String(cfg.variables![k])) : [] const { whatsapp_message_id } = await engineSendTemplate({