JS Preprocessor Explained
Use the JS Preprocessor to normalize, validate, and promote values from params._gpt (written by the AI Preprocessor – Data Extraction) into your canonical params keys before webhooks, lookup tables, or routing run.
Execution Contract
-
Input: params (mutable object for the current session)
-
Output: return the (optionally) mutated params
-
Order: Runs after the AI Preprocessor (so params._gpt is available) and before Lookup Tables/Webhooks.
Note:
Any changes you make to params inside the JS Preprocessor—or any value you return—will be available for use in the rest of the plugin execution. Returned values are stored under the _js namespace and can be referenced anywhere in the workflow.
Minimal Template
(params) => {
if (!params.leadId) {
throw new Error('lead id is missing');
}
return {
fullname: (params._gpt?.taalk_first_name || "Someone") + "," + (params._gpt?.taalk_last_name || "")
};
}
If you later want to use the generated fullname in a message, webhook, or condition, you can reference it as:
<_js.fullname>
Key points:
-
Returning an object makes those values available as _js.keyName throughout the rest of the plugin.
-
Throwing an error in the preprocessor will stop execution and surface the error message in logs.
-
You can mix returning new values with modifying params directly if you want both _js scoped and global context variables.
Patterns & Tips
-
Non‑destructive promotion: Only write to params[...] if the key is empty. Let CRMs/Lookups overwrite explicitly later if needed.
-
Segment‑aware logic: Branch on params._gpt.segment to change behavior Before Transfer vs After Transfer (e.g., which fields to expect).
-
PII hygiene: Avoid logging the entire params object. Use a _log_safe subset with redaction.
-
Fallbacks: If _gpt is missing or has error, set params._extraction_status and route to a safe path (e.g., human review or re‑prompt).
Common Extensions
1) Strict Required Fields Gate
const requireAll = (...keys) => keys.every(k => params[k] != null && params[k] !== "");
params._ready_for_webhook = requireAll("contact_first_name","contact_phone","move_date_iso");
2) Normalize Phone & Email
const normPhone = p => (p || "").replace(/[^\d+]/g, "");
if (params.contact_phone) params.contact_phone = normPhone(params.contact_phone);
if (params.contact_email) params.contact_email = params.contact_email.trim().toLowerCase();
3) Promote to Lookup Keys
// Example: map into keys your Lookup Table expects
params.lookup_key_state = params.state || pick("taalk_state");
params.lookup_key_service = params.move_service_type || "full_move";
4) Merge with Existing CRM Data
// Keep CRM truth unless missing; only fill gaps from extraction
const prefer = (a, b) => (a != null && a !== "" ? a : b);
params.contact_first_name = prefer(params.contact_first_name, pick("taalk_first_name"));