String Snippets
Custom Code Snippets — Strings & Names
Copy-paste examples for building names, slugs, titles, IDs from text, and templated email bodies inside a Custom Code workflow step. Each snippet uses only the helpers the sandbox exposes — Str, plain JavaScript, and the standard regex engine.
The Str helper covers what you'll reach for most often: capitalize, lowercase, uppercase, trim, slug, truncate, contains, startsWith, endsWith, replace, split, join.
Build a full name from first + last
const first = Str.trim(record.first_name || "");
const last = Str.trim(record.last_name || "");
const full = [first, last].filter(Boolean).join(" ") || "Unnamed";
returnData("full_name", full);
returnData("initials", `${first.charAt(0)}${last.charAt(0)}`.toUpperCase());
Build a formal salutation ("Dear Mr. Smith,")
// Inputs: title (custom_val "Mr."/"Ms."/"Dr."), last_name (record_val)
const title = Str.trim(params["title"] || "");
const last = Str.trim(record.last_name || "");
const salutation = (title && last)
? `Dear ${title} ${last},`
: (last ? `Dear ${last},` : "Hello,");
returnData("salutation", salutation);
Title-case a messy string
// Inputs: raw_title (custom_val or record_val)
const raw = params["raw_title"] || "";
const titled = raw
.toLowerCase()
.split(/\s+/)
.map(w => Str.capitalize(w))
.join(" ");
returnData("title", titled);
Build a URL slug
// "Hello World!! v2" -> "hello-world-v2"
const slug = Str.slug(params["title"] || record.name || "untitled");
returnData("slug", slug);
Truncate with ellipsis
// Inputs: body (record_val), max_chars (custom_val, e.g. 140)
const max = Number(params["max_chars"]) || 140;
returnData("preview", Str.truncate(params["body"] || "", max));
Compose a templated email body
const user = loggedInUser || {};
const order = params["order_obj"] || {};
const body = [
`Hi ${Str.capitalize(user.first_name || "there")},`,
``,
`Thanks for order #${order.id}. Your total was $${Num.format(order.total || 0, 2)}.`,
`We'll email tracking once it ships.`,
``,
`— The Team`
].join("\n");
returnData("email_body", body);
returnData("email_subject", `Order #${order.id} confirmed`);
Mask part of a string (last-4 of a card or SSN)
// Inputs: card_number (custom_val "4242424242424242")
const raw = (params["card_number"] || "").replace(/\D/g, "");
const last4 = raw.slice(-4);
const masked = raw.length > 4
? `${"*".repeat(raw.length - 4)}${last4}`
: raw;
returnData("masked", masked);
returnData("last4", last4);
Replace {{tokens}} in a template string
// Inputs: template (custom_val) e.g. "Hi {{name}}, your code is {{code}}"
const template = params["template"] || "";
const values = {
name: loggedInUser.first_name || "there",
code: crypto.randomUUID().slice(0, 6).toUpperCase(),
brand: getAppDetails("name", "Our App")
};
const rendered = template.replace(/\{\{\s*(\w+)\s*\}\}/g, (_, key) =>
Object.prototype.hasOwnProperty.call(values, key) ? String(values[key]) : ""
);
returnData("rendered", rendered);
Extract the domain from an email
// "ada@acme.co.uk" -> "acme.co.uk"
const email = (params["email"] || record.email || "").toLowerCase().trim();
const at = email.indexOf("@");
const domain = at > -1 ? email.slice(at + 1) : "";
returnData("domain", domain);
returnData("is_gmail", domain === "gmail.com");
Escape a value safely for a CSV cell
// Inputs: value (record_val)
function csvEscape(v) {
const s = String(v == null ? "" : v);
if (/[",\r\n]/.test(s)) return `"${s.replace(/"/g, '""')}"`;
return s;
}
returnData("csv_cell", csvEscape(params["value"]));
Strip HTML tags down to plain text
// "<p>Hi <b>there</b>!</p>" -> "Hi there!"
const html = params["html_body"] || record.body || "";
const plain = html
.replace(/<br\s*\/?>/gi, "\n")
.replace(/<[^>]+>/g, "")
.replace(/ /g, " ")
.replace(/&/g, "&")
.replace(/[ \t]+\n/g, "\n")
.trim();
returnData("plain_text", plain);
returnData("char_count", plain.length);
Pad a numeric ID to a fixed width
// 42 -> "INV-000042"
const n = Number(params["invoice_number"]) || 0;
const padded = String(n).padStart(6, "0");
returnData("invoice_code", `INV-${padded}`);
Word count and reading time
// Inputs: body (record_val)
const text = (params["body"] || "").trim();
const words = text ? text.split(/\s+/).length : 0;
returnData("word_count", words);
returnData("reading_minutes", Math.max(1, Math.ceil(words / 200)));
Check if a string contains any term from a list
// Useful for keyword tagging / spam filters
const haystack = (params["text"] || record.body || "").toLowerCase();
const flagged = ["urgent", "asap", "immediately", "lawsuit"];
const hits = flagged.filter(term => haystack.includes(term));
returnData("flagged", hits.length > 0);
returnData("flagged_terms", hits);
Trim emoji and non-ASCII from a name
// "John 🎉 Smith" -> "John Smith"
const cleaned = (params["name"] || record.first_name || "")
.replace(/[^\x20-\x7E]/g, "")
.replace(/\s+/g, " ")
.trim();
returnData("clean_name", cleaned);
We'd love to hear your feedback.