Using custom code steps in action flows

<div class="article-banners">
<div id="docs-wmp-link">
<a href="https://support.zendesk.com/hc/en-us/articles/5411234991258-plan" rel="noopener" target="_blank">What's my plan?</a>
</div>
<div class="article-banner" id="suite_gpee">
<table>
<tbody>
<tr>
<td>
<strong>All Suites</strong>
</td>
<td>Growth, Professional, Enterprise, or Enterprise Plus</td>
</tr>
</tbody>
</table>
</div>
<div class="article-banner" id="support_all">
<table>
<tbody>
<tr>
<td>
<strong>Support</strong>
</td>
<td>Team, Professional, or Enterprise</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="body">
<p class="p">An <a class="xref" href="https://support.zendesk.com/hc/en-us/articles/8855513857306" target="_blank">action flow</a> is a user-defined automated workflow. Each
action flow consists of an action flow trigger, which initiates the flow, and one or
more actions. </p>
<p class="p">Custom code steps let you execute custom JavaScript to perform complex data
transformations, formatting, and advanced logic that aren't possible with the predefined
actions and steps. For example, you might use a custom code step to take information to
mask sensitive parts of an email address, validate the format of an email or order ID,
or even calculate future dates for follow-up reminders.</p>
<div class="p">This article contains the following topics:<ul class="ul" id="topic_j3q_zv1_chc__ul_ipq_fcb_chc">
<li class="li"><a class="xref" href="#topic_j3q_xdb_chc">Adding and configuring custom code steps</a></li>
<li class="li"><a class="xref" href="#topic_txg_s3c_chc">Supported data types for custom code inputs and outputs</a></li>
<li class="li"><a class="xref" href="#topic_hmv_ydb_chc">AI prompt templates for generating custom JavaScript code for your action flow step</a></li>
<li class="li"><a class="xref" href="#topic_cvv_tnc_chc">Examples custom code steps</a></li>
</ul>
</div>
<div class="note attention">
<span class="attentiontitle"></span> <strong class="ph b">Disclaimer: </strong>The example JavaScript for Action Builder’s custom
code step is provided for informational purposes only on an ‘as is’ basis. Zendesk does
not guarantee they will work for your use case and does not provide support for writing
or debugging custom JavaScript. Test in a test environment and do not include secrets or
other sensitive data.</div>
</div>
<div aria-labelledby="ariaid-title2" class="topic nested1" id="topic_j3q_xdb_chc">
<h2 class="title topictitle2" id="ariaid-title2">Adding and configuring custom code steps</h2>
<div class="body">
<p class="p">If you need to execute code as part of an action flow, you can add a custom code
step. See <a class="xref" href="#topic_txg_s3c_chc">Supported data types</a>
to learn which data types are supported for inputs and outputs of custom code
steps.</p>
<div class="p">
<strong class="ph b">To add custom code to an action flow</strong><ol class="ol" id="topic_j3q_xdb_chc__ol_rgd_mqk_t2c">
<li class="li"><a class="xref" href="https://support.zendesk.com/hc/en-us/articles/9052312956570#topic_ant_ttk_t2c" target="_blank">Open an action flow.</a></li>
<li class="li">In the action builder, beneath an existing step, click the <strong class="ph b">Add step</strong>
icon (<img class="image" id="topic_j3q_xdb_chc__image_ggh_fbg_w2c" src="https://zen-marketing-documentation.s3.amazonaws.com/docs/en/icon_action_flows_add.png" width="16">).</li>
<li class="li">In the step sidebar, under <strong class="ph b">Flow control and utilities</strong>, click
<strong class="ph b">Custom code</strong>.</li>
<li class="li">In the step sidebar, click <strong class="ph b">Add input</strong> to <a class="xref" href="#topic_ssr_12b_chc">add inputs for the custom
code</a>.</li>
<li class="li">In the step sidebar, click <strong class="ph b">Add output</strong> to <a class="xref" href="#topic_qvx_b2b_chc">add at least one
output</a>.</li>
<li class="li">In the step sidebar, under <strong class="ph b">Code</strong>, <a class="xref" href="#topic_m3s_c2b_chc">enter your custom JavaScript code</a>.</li>
<li class="li">Click <strong class="ph b">Save</strong>.</li>
</ol>
</div>
<p class="p">To ensure the custom code is working as expected, <a class="xref" href="https://support.zendesk.com/hc/en-us/articles/9052312956570#topic_uyj_qsw_3fc" target="_blank">test your action flow</a>. If you run into
issues, see <a class="xref" href="https://support.zendesk.com/hc/en-us/articles/9052312956570#topic_obr_cfb_chc" target="_blank">Troubleshooting custom code steps</a>.</p>
</div>
<div aria-labelledby="ariaid-title3" class="topic nested2" id="topic_ssr_12b_chc">
<h3 class="title topictitle3" id="ariaid-title3">Adding inputs to custom code steps</h3>
<div class="body">
<p class="p">Custom code steps can have a maximum of 50 inputs.</p>
<div class="p">
<strong class="ph b">To add inputs to a custom code step</strong><ol class="ol" id="topic_ssr_12b_chc__ol_myl_j3c_chc">
<li class="li">
<a class="xref" href="https://support.zendesk.com/hc/en-us/articles/9052312956570#topic_ant_ttk_t2c" target="_blank">Open an action flow</a>.</li>
<li class="li">In the action builder, click on an existing custom code step or click
the <strong class="ph b">Add step</strong> icon (<img class="image" id="topic_ssr_12b_chc__image_mwp_qjc_chc" src="https://zen-marketing-documentation.s3.amazonaws.com/docs/en/icon_action_flows_add.png" width="16">) to <a class="xref" href="#topic_j3q_xdb_chc">add a custom code
step</a>.</li>
<li class="li">In the step sidebar, click <strong class="ph b">Add input</strong>.</li>
<li class="li">Under <strong class="ph b">Select variable</strong>, select a variable from a previous step or
the action flow trigger.<div class="note note">
<span class="notetitle">Note:</span> The input's data type is inferred from the
selected variable.</div>
</li>
<li class="li">Verify the input's <strong class="ph b">Name</strong> value, which is automatically populated
based on the selected variable but can be edited. Input names must
adhere to these <a class="xref" href="https://support.zendesk.com/hc/en-us/articles/8855601898266#topic_gsd_llc_chc" target="_blank">requirements</a>.</li>
<li class="li">Click <strong class="ph b">Save</strong>.</li>
</ol>
</div>
</div>
</div>
<div aria-labelledby="ariaid-title4" class="topic nested2" id="topic_qvx_b2b_chc">
<h3 class="title topictitle3" id="ariaid-title4">Adding outputs to custom code steps</h3>
<div class="body">
<div class="p">Custom code steps must have at least 1 output and up to 50 outputs.<div class="note note">
<span class="notetitle">Note:</span> Your
custom code must return a value for each defined output.</div>
</div>
<div class="p">
<strong class="ph b">To add outputs to a custom code step</strong><ol class="ol" id="topic_qvx_b2b_chc__ol_vjh_xlc_chc">
<li class="li">
<a class="xref" href="https://support.zendesk.com/hc/en-us/articles/9052312956570#topic_ant_ttk_t2c" target="_blank">Open an action flow</a>.</li>
<li class="li">In the action builder, click on an existing custom code step or click
the <strong class="ph b">Add step</strong> icon (<img class="image" id="topic_qvx_b2b_chc__image_wjh_xlc_chc" src="https://zen-marketing-documentation.s3.amazonaws.com/docs/en/icon_action_flows_add.png" width="16">) to <a class="xref" href="#topic_j3q_xdb_chc">add a custom code
step</a>.</li>
<li class="li">In the step sidebar, click <strong class="ph b">Add output</strong>.</li>
<li class="li">Enter a unique <strong class="ph b">Name</strong> for the output.<p class="p">It must adhere to these
<a class="xref" href="https://support.zendesk.com/hc/en-us/articles/8855601898266#topic_gsd_llc_chc" target="_blank">requirements</a>.</p>
</li>
<li class="li">Select the output's data <strong class="ph b">Type</strong>.</li>
<li class="li">Click <strong class="ph b">Save</strong>.</li>
</ol>
</div>
</div>
</div>
<div aria-labelledby="ariaid-title5" class="topic nested2" id="topic_m3s_c2b_chc">
<h3 class="title topictitle3" id="ariaid-title5">Adding your custom code</h3>
<div class="body">
<p class="p">The JavaScript in custom code steps must export a function that takes an
<em class="ph i">inputs</em> object and returns an <em class="ph i">outputs</em> object. Each time you add
a custom code step to an action flow, it is prepoulated with this framework,
which you can modify, expand upon, or delete and start fresh.</p>
<p class="p">Although the custom code step is designed to be as user-friendly as possible,
admins might still require engineering support when implementing these
steps.</p>
<div class="p">Keep the following requirements, limitations, and restrictions in mind:<ul class="ul">
<li class="li">The code for a step can be a maximum of 10,000 characters.</li>
<li class="li">Your custom code must return a value for each <a class="xref" href="#topic_qvx_b2b_chc">output</a> defined for
the step.</li>
<li class="li">The code you use in action flows must execute quickly and use a
reasonable amount of memory.</li>
<li class="li">The following JavaScript restrictions apply:<ul class="ul" id="topic_m3s_c2b_chc__ul_e2m_fgc_chc">
<li class="li">The function must be synchronous. That means
<code class="ph codeph">async</code>, <code class="ph codeph">await</code>, and
<code class="ph codeph">promise</code> aren't supported.</li>
<li class="li">Network requests, such as <code class="ph codeph">fetch</code>,
<code class="ph codeph">XMLHttpRequest</code>, and jQuery AJAX arent't
supported.</li>
<li class="li">You can't <code class="ph codeph">import</code> or <code class="ph codeph">require</code>
external libraries or modules.</li>
</ul>
</li>
</ul>
</div>
<div class="p">
<strong class="ph b">To add your custom code</strong><ol class="ol" id="topic_m3s_c2b_chc__ol_jbj_l3c_chc">
<li class="li">
<a class="xref" href="https://support.zendesk.com/hc/en-us/articles/9052312956570#topic_ant_ttk_t2c" target="_blank">Open an action flow</a>.</li>
<li class="li">In the action builder, click on an existing custom code step or click
the <strong class="ph b">Add step</strong> icon (<img class="image" id="topic_m3s_c2b_chc__image_w3m_1nc_chc" src="https://zen-marketing-documentation.s3.amazonaws.com/docs/en/icon_action_flows_add.png" width="16">) to <a class="xref" href="#topic_j3q_xdb_chc">add a custom code
step</a>.</li>
<li class="li">Under <strong class="ph b">Code</strong>, expand upon the provided example, delete the example
and write your own logic, or use an <a class="xref" href="#topic_hmv_ydb_chc">AI prompt</a> to generate custom code for
you.<div class="p">Your code must export a function that takes an <em class="ph i">inputs</em>
object and returns an <em class="ph i">outputs</em> object. For
example:<pre class="pre codeblock" id="topic_m3s_c2b_chc__codeblock_gh3_nz4_bhc"><code>// In the Inputs section for this step, add an input named status.
// In the Outputs section for this step, add a text output named message.

module.exports = (inputs) =&gt; {
// Access inputs using inputs.&lt;name&gt;
const msg = 'Your text was ' + inputs.status + '.'

// This return must include all outputs.
return {
message: msg
}
}</code></pre>
</div>
<div class="note note">
<span class="notetitle">Note:</span> As
you write your code, the editor offers helpful suggestions for valid
JavaScript operations. Typos and invalid code are marked with a
squiggly, red underline. Hover your mouse over the underlined
section to view the error message.</div>
</li>
<li class="li">Click <strong class="ph b">Save</strong>.</li>
</ol>
</div>
</div>
</div>
</div>
<div aria-labelledby="ariaid-title6" class="topic nested1" id="topic_txg_s3c_chc">
<h2 class="title topictitle2" id="ariaid-title6">Supported data types for custom code inputs and outputs</h2>
<div class="body">
<p class="p">The custom code step accepts and returns the following data types, each of which
appears in your code as the equivalent JavaScript type.</p>
<div class="tablenoborder">
<table border="1" cellpadding="4" cellspacing="0" class="table" frame="border" id="topic_txg_s3c_chc__table_tfv_nt4_bhc" rules="all" summary="">
<colgroup>
<col style="width:33.33333333333333%">
<col style="width:33.33333333333333%">
<col style="width:33.33333333333333%">
</colgroup>
<thead class="thead" style="text-align:left;">
<tr class="row">
<th class="entry cellrowborder" id="d52e445" style="vertical-align:top;">Input type</th>
<th class="entry cellrowborder" id="d52e448" style="vertical-align:top;">JavaScript data type</th>
<th class="entry cellrowborder" id="d52e451" style="vertical-align:top;">Example</th>
</tr>
</thead>
<tbody class="tbody">
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">Text</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">string</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">"Hello there!"</td>
</tr>
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">Number</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">number</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">123, -5, 0</td>
</tr>
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">Decimal</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">number</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">12.67, 1.0, 0.0</td>
</tr>
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">True/false</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">boolean</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">true, false</td>
</tr>
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">Date*</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">string</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">"2025-10-27"</td>
</tr>
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">Date and time*</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">string</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">
<p class="p">A UTC date and time</p>
<p class="p">"2025-10-27T10:30:00Z"</p>
<p class="p">A date
and time with a time zone
offset:</p>
<p class="p">"2025-06-22T05:11:28+10:00"</p>
<p class="p">A UTC date and
time with milliseconds:</p>
<p class="p">"2025-03-08T06:01:21.415Z"</p>
A
date and time with a time zone offset and
milliseconds:"2025-07-23T13:33:17.031-3:00"</td>
</tr>
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">Text array</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">array of strings</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">["Hello there!", "How are you"]</td>
</tr>
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">Number array</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">array of numbers</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">[12, 34, 56, 0]</td>
</tr>
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">Decimal array</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">array of numbers</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">[2.1, 6.3, 6.01, 0.1]</td>
</tr>
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">True/false array</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">array of booleans</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">[true, true, false]</td>
</tr>
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">Date array</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">array of strings</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">["1997-08-29", "2004-07-25", "2011-04-21"]</td>
</tr>
<tr class="row">
<td class="entry cellrowborder" headers="d52e445" style="vertical-align:top;">Datetime array</td>
<td class="entry cellrowborder" headers="d52e448" style="vertical-align:top;">array of strings</td>
<td class="entry cellrowborder" headers="d52e451" style="vertical-align:top;">["1977-05-25T12:45Z", "1980-05-21T15:00Z",
"1983-05-25T19:30Z"]</td>
</tr>
</tbody>
</table>
</div>
<div class="note note" id="topic_txg_s3c_chc__note_ftm_rw4_bhc">
<span class="notetitle">Note:</span> * Date and datetime inputs are provided to your code as
strings. To perform date operations, convert these values to JavaScript Date objects
first.</div>
<div class="p">The following data types below aren’t supported as outputs. If you need to return one
of these types, convert it to a string before outputting it as a Text or Text
array:<ul class="ul" id="topic_txg_s3c_chc__ul_y3n_mlb_chc">
<li class="li">Object</li>
<li class="li">Object array</li>
<li class="li">Mixed array</li>
<li class="li">Array array</li>
</ul>
</div>
</div>
</div>
<div aria-labelledby="ariaid-title7" class="topic nested1" id="topic_hmv_ydb_chc">
<h2 class="title topictitle2" id="ariaid-title7">AI prompt templates for generating custom JavaScript code for your action flow step</h2>
<div class="body">
<p class="p">The following prompts can be used with AI tools, such as ChatGPT, to generate code
for your custom code step. The pompts include guidance about the supported data
types and the required structure for the code.</p>
</div>
<div aria-labelledby="ariaid-title8" class="topic nested2" id="topic_ds5_ync_chc">
<h3 class="title topictitle3" id="ariaid-title8">Prompt 1</h3>
<div class="body">
<pre class="pre codeblock" id="topic_ds5_ync_chc__codeblock_d1j_pdp_bhc"><code>Write a piece of JavaScript code. The code must export a function that takes an inputs object and returns an outputs object, for example:

module.exports = (inputs) =&gt; {
let msg = "Your text was " + inputs.inputText + "."
return {
outputMessage: msg
}
}

Supported data types:
Strings, numbers, booleans, dates (YY-MM-DD) and datetimes (YY-MM-DDTHH:mm:SSZ) are supported. Arrays of those are supported too.

Objects, arrays of arrays, and arrays of objects are not supported. When used as inputs or outputs they must be stringified and passed as strings.

Check for missing or invalid data, and ensure it is handled gracefully by returning a valid output:

for strings, output the empty string ""
for numbers, output -1
for booleans, output false
for arrays, output the empty array []
for objects, output the empty object {}

Comment the code:

Include a comment at the top which briefly describes what the code does.

Include comments directing the reader to create the inputs and outputs, for example: // Make sure to create the following inputs: field_tag (Text).
In comments, refer to variable types with the following friendly names:
string: use "Date" for dates, "Date and time" for datetimes, else use "Text"
number: use "Number” or "Decimal"
boolean: use "True/False"
array: use "Number array", "Text array" etc

The code should... &lt;DESCRIBE WHAT YOU WANT YOUR CODE TO DO HERE&gt;</code></pre>
</div>
</div>
<div aria-labelledby="ariaid-title9" class="topic nested2" id="topic_f4y_y4c_chc">
<h3 class="title topictitle3" id="ariaid-title9">Prompt 2</h3>
<div class="body">
<pre class="pre codeblock" id="topic_f4y_y4c_chc__codeblock_znd_qdp_bhc"><code>Write a piece of JavaScript code. The code must export a function that takes an inputs object and returns an outputs object, for example:

module.exports = (inputs) =&gt; {
let msg = "Your text was " + inputs.inputText + "."
return {
outputMessage: msg
}
}

Supported input and output data types:
Strings, numbers, booleans, dates (YY-MM-DD) and datetimes (YY-MM-DDTHH:mm:SSZ) are supported. Arrays of those are supported too.

Objects, arrays of arrays, and arrays of objects are not supported. When used as inputs or outputs they must be stringified and passed as strings.

Comment the code:

Include a comment at the top which briefly describes what the code does.

Include comments directing the reader to create the inputs and outputs, for example: // Make sure to create the following inputs: field_tag (Text).
In comments, refer to variable types with the following friendly names:
string: use "Date" for dates, "Date and time" for datetimes, else use "Text"
number: use "Number" or "Decimal"
boolean: use "True/False"
array: use "Number array", "Text array" etc

The code should... &lt;DESCRIBE WHAT YOU WANT YOUR CODE TO DO HERE&gt;
</code></pre>
</div>
</div>
</div>
<div aria-labelledby="ariaid-title10" class="topic nested1" id="topic_cvv_tnc_chc">
<h2 class="title topictitle2" id="ariaid-title10">Examples custom code steps</h2>
<div class="body">
<div class="p">The following examples demonstrate how the custom code step can be used to address
common automation scenarios:<ul class="ul" id="topic_cvv_tnc_chc__ul_wm1_2pc_chc">
<li class="li"><a class="xref" href="#topic_ey3_fpc_chc">Formatting basic ticket details into a human-readable comment</a></li>
<li class="li"><a class="xref" href="#topic_htc_3pc_chc">Calculating the next hour from now</a></li>
<li class="li"><a class="xref" href="#topic_ysh_lpc_chc">Validating the formatting of an email address</a></li>
<li class="li"><a class="xref" href="#topic_rjf_npc_chc">Masking an email address</a></li>
<li class="li"><a class="xref" href="#topic_lrd_qpc_chc">Mapping an internal identifier to a human-readable name</a></li>
<li class="li"><a class="xref" href="#topic_isp_5pc_chc">Checking whether any items in a list begin with specific characters</a></li>
<li class="li"><a class="xref" href="#topic_upl_bqc_chc">Comparing two lists of values</a></li>
<li class="li"><a class="xref" href="#topic_c3y_fqc_chc">Finding an order ID within text</a></li>
<li class="li"><a class="xref" href="#topic_pnm_jqc_chc">Generating a random number</a></li>
<li class="li"><a class="xref" href="#topic_nzz_mqc_chc">Generating three random numbers between one and seven</a></li>
</ul>
</div>
<div class="note note">
<span class="notetitle">Note:</span> Zendesk provides these JavaScript examples for instructional purposes only.
Zendesk does not guarantee compatibility with your specific use case and does not
offer support for writing or debugging custom JavaScript. Always test code in a test
environment first, and avoid including sensitive data.</div>
</div>
<div aria-labelledby="ariaid-title11" class="topic nested2" id="topic_ey3_fpc_chc">
<h3 class="title topictitle3" id="ariaid-title11">Formatting basic ticket details into a human-readable comment</h3>
<div class="body">
<pre class="pre codeblock" id="topic_ey3_fpc_chc__codeblock_uvx_qbp_bhc"><code>module.exports = (inputs) =&gt; {
// This code takes text inputs 'status' and 'priority', and a number input 'ticket_id', and outputs a friendly message combining these values.

// Make sure to create the following inputs:
// status (Text)
// priority (Text)
// ticket_id (Number)

const message = `Ticket ${inputs.ticket_id} has status ${inputs.status} and priority ${inputs.priority}.`

// Make sure to create the following outputs:
// message (Text)
return {
message,
}
}</code></pre>
</div>
</div>
<div aria-labelledby="ariaid-title12" class="topic nested2" id="topic_htc_3pc_chc">
<h3 class="title topictitle3" id="ariaid-title12">Calculating the next hour from now</h3>
<div class="body">
<p class="p">In the example, the time is currently 2025-10-27T09:17:00Z. Therefore, the
following code returns 2025-10-27T10:00:00Z.</p>
<pre class="pre codeblock" id="topic_htc_3pc_chc__codeblock_i1z_tbp_bhc"><code>module.exports = (inputs) =&gt; {
// This code calculates the next full hour from the current UTC time

// No inputs required

// Make sure to create the following outputs:
// nextHour (Date and time)

// Create a Date object for the current time
const nextHour = new Date()

// Round up to the next hour by:
// 1. Setting minutes, seconds, and milliseconds to 0
nextHour.setUTCMinutes(0, 0, 0)
// 2. Adding 1 hour
nextHour.setUTCHours(nextHour.getUTCHours() + 1)

return {
nextHour: nextHour.toISOString(),
}
}</code></pre>
</div>
</div>
<div aria-labelledby="ariaid-title13" class="topic nested2" id="topic_ysh_lpc_chc">
<h3 class="title topictitle3" id="ariaid-title13">Validating the formatting of an email address</h3>
<div class="body">
<pre class="pre codeblock" id="topic_ysh_lpc_chc__codeblock_xqn_wbp_bhc"><code>module.exports = (inputs) =&gt; {
// This code takes a text input 'emailAddress',
// uses regex to do a basic check whether it is a valid email format,
// and outputs a boolean 'emailIsValid'.

// Make sure to create the following inputs:
// emailAddress (Text)

// Simple email regex pattern
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/

const emailIsValid = emailRegex.test(inputs.emailAddress)

// Make sure to create the following outputs:
// emailIsValid (True/False)

return {
emailIsValid
}
}
</code></pre>
</div>
</div>
<div aria-labelledby="ariaid-title14" class="topic nested2" id="topic_rjf_npc_chc">
<h3 class="title topictitle3" id="ariaid-title14">Masking an email address</h3>
<div class="body">
<p class="p">This example replaces portions of an email address with asterisk characters. For
example, "Could you please confirm your email address is
d******n@zendesk.com?"</p>
<pre class="pre codeblock" id="topic_rjf_npc_chc__codeblock_vwl_2cp_bhc"><code>// This code takes an email address input and returns a masked version where the local part is partially replaced with '*', preserving the first and last characters.

// Make sure to create the following input:
// emailToMask (Text)

// Make sure to create the following output:
// maskedEmail (Text)

module.exports = (inputs) =&gt; {

const [emailName, emailDomain] = inputs.emailToMask.split("@")

let maskedEmailName = emailName

if (emailName.length &gt; 2) {
maskedEmailName = emailName[0]
maskedEmailName += "*".repeat(emailName.length-2)
maskedEmailName += emailName[emailName.length-1]
}

return {
maskedEmail: `${maskedEmailName}@${emailDomain}`
}
}
</code></pre>
</div>
</div>
<div aria-labelledby="ariaid-title15" class="topic nested2" id="topic_lrd_qpc_chc">
<h3 class="title topictitle3" id="ariaid-title15">Mapping an internal identifier to a human-readable name</h3>
<div class="body">
<p class="p">Mappings like this are useful for converting internal ids, such as a dropdown
ticket field’s tag, to more user-friendly names like a value shown in a
dropdown.</p>
<div class="p">You can use this approach for tasks such as:<ul class="ul" id="topic_lrd_qpc_chc__ul_jr3_kcp_bhc">
<li class="li">Translating Slack channel ids to channel names</li>
<li class="li">Converting JIRA project ids to project names</li>
<li class="li">Mapping Zendesk ticket statuses to corresponding JIRA issue
statuses</li>
</ul>
</div>
<pre class="pre codeblock" id="topic_lrd_qpc_chc__codeblock_rwg_ncp_bhc"><code>const optionMap = {
option_01_ivory: 'ivory',
option_02_cream: 'cream',
option_03_white: 'white',
option_04_bone: 'bone',
}

module.exports = (inputs) =&gt; {
// This code takes a text input 'optionTag',
// and outputs the corresponding 'optionName' based on a predefined mapping.
// If the input is missing or does not match any tag, it returns an empty string.

// Make sure to create the following inputs:
// optionTag (Text)

const optionName = optionMap[inputs.optionTag] || ''

// Make sure to create the following outputs:
// optionName (Text)

return {
optionName,
}
}</code></pre>
</div>
</div>
<div aria-labelledby="ariaid-title16" class="topic nested2" id="topic_isp_5pc_chc">
<h3 class="title topictitle3" id="ariaid-title16">Checking whether any items in a list begin with specific characters</h3>
<div class="body">
<p class="p">This example checks whether any items in a list begin with specific characters.
For example, if you're searching for items beginning with “customer” and your
list of tags contains [“critical_bug”, “customer_24601”, “escalation”], the
result would be <code class="ph codeph">true</code> because “customer_24601” begins with
“customer”.</p>
<pre class="pre codeblock" id="topic_isp_5pc_chc__codeblock_q3d_rcp_bhc"><code>module.exports = (inputs) =&gt; {
// This code takes a text array 'tags' and a text string 'searchTerm',
// and outputs a boolean 'matchFound' indicating whether any tag begins with the searchTerm.

// Make sure to create the following inputs:
// tags (Text array)
// searchTerm (Text)

const matchFound = inputs.tags.some(tag =&gt; tag.startsWith(inputs.searchTerm))

// Make sure to create the following outputs:
// matchFound (True/False)

return {
matchFound
}
}</code></pre>
</div>
</div>
<div aria-labelledby="ariaid-title17" class="topic nested2" id="topic_upl_bqc_chc">
<h3 class="title topictitle3" id="ariaid-title17">Comparing two lists of values</h3>
<div class="body">
<p class="p">This example compares two lists and removes all values from the first list that
are also present in the second.</p>
<p class="p"> For example, given a list of ticket CCs and a list of disallowed users, any
disallowed users found in the CC list will be excluded from the output list
(<code class="ph codeph">cleanCCs</code>). This method can also be used to filter out tags
that should be removed from a ticket or user.</p>
<pre class="pre codeblock" id="topic_upl_bqc_chc__codeblock_ing_wcp_bhc"><code>module.exports = (inputs) =&gt; {
// This code takes two number arrays: ticketCCs and disallowedUsers,
// and outputs a number array cleanCCs which includes only those items from ticketCCs that are NOT in disallowedUsers.

// Make sure to create the following inputs:
// ticketCCs (Number array)
// disallowedUsers (Number array)

const cleanCCs = inputs.ticketCCs.filter(cc =&gt; !inputs.disallowedUsers.includes(cc))

// Make sure to create the following outputs:
// cleanCCs (Number array)

return {
cleanCCs,
}
}
</code></pre>
</div>
</div>
<div aria-labelledby="ariaid-title18" class="topic nested2" id="topic_c3y_fqc_chc">
<h3 class="title topictitle3" id="ariaid-title18">Finding an order ID within text</h3>
<div class="body">
<p class="p">This example extracts an order ID from a string of text, such as a ticket
comment. You can adjust the regular expression (<code class="ph codeph">/GO-\d{8,9}/</code>)
as needed to match your specific order ID format.</p>
<pre class="pre codeblock" id="topic_c3y_fqc_chc__codeblock_rfn_1dp_bhc"><code>// Regex for order number: "GO-" followed by 8 or 9 digits
const ORDER_NUMBER_REGEX = /GO-\d{8,9}/

// Searches comment for order number and returns it if found.
const findOrderNumber = comment =&gt; comment.match(ORDER_NUMBER_REGEX)[0]

module.exports = (inputs) =&gt; {
// This code uses regex to look for an orderNumber with pattern "GO-" followed by 8 or 9 digits

// Make sure to create the following inputs:
// commentBody (Text)

const orderNumber = findOrderNumber(inputs.commentBody)

// Make sure to create the following outputs:
// orderNumber (Text)
// matchFound (True/False)

return {
orderNumber,
matchFound: Boolean(orderNumber),
}
}
</code></pre>
</div>
</div>
<div aria-labelledby="ariaid-title19" class="topic nested2" id="topic_pnm_jqc_chc">
<h3 class="title topictitle3" id="ariaid-title19">Generating a random number</h3>
<div class="body">
<p class="p">This example generates a random number within the boundaries you specify. You can
change the value <code class="ph codeph">52</code> to set your desired upper limit for the
random number.</p>
<pre class="pre codeblock" id="topic_pnm_jqc_chc__codeblock_dj4_fdp_bhc"><code>module.exports = (inputs) =&gt; {
// This code outputs a random integer number between 1 and 52 inclusive.

// No inputs required.

// Make sure to create the following outputs:
// randomNumber (Number)

const randomNumber = Math.floor(Math.random() * 52) + 1

return {
randomNumber
}
}
</code></pre>
</div>
</div>
<div aria-labelledby="ariaid-title20" class="topic nested2" id="topic_nzz_mqc_chc">
<h3 class="title topictitle3" id="ariaid-title20">Generating three random numbers between one and seven</h3>
<div class="body">
<div class="p">The following example returns three random numbers as individual
outputs:<pre class="pre codeblock" id="topic_nzz_mqc_chc__codeblock_o1z_jdp_bhc"><code>module.exports = (inputs) =&gt; {
// This code outputs three unique random integer numbers between 1 and 7 inclusive.

// No inputs required.

// Make sure to create the following outputs:
// randomNumber1 (Number)
// randomNumber2 (Number)
// randomNumber3 (Number)

const numbers = new Array()
while (numbers.length &lt; 3) {
const candidate = Math.floor(Math.random() * 7) + 1
if (!numbers.includes(candidate)) {
numbers.push(candidate)
}
}

return {
randomNumber1: numbers[0],
randomNumber2: numbers[1],
randomNumber3: numbers[2]
}
}
</code></pre>
</div>
<div class="p">This example returns three random numbers in an array rather than
individually:<pre class="pre codeblock" id="topic_nzz_mqc_chc__codeblock_djb_mdp_bhc"><code>module.exports = (inputs) =&gt; {
// This code outputs an array of three unique random numbers between 1 and 7 inclusive.

// No inputs required.

// Make sure to create the following outputs:
// randomNumbers (Number array)

const numbers = new Array()
while (numbers.length &lt; 3) {
const candidate = Math.floor(Math.random() * 7) + 1
if (!numbers.includes(candidate)) {
numbers.push(candidate)
}
}

return {
randomNumbers: numbers
}
}
</code></pre>
</div>
</div>
</div>
</div>
<script id="docs-schema-markup" type="application/ld+json">{
"@context": "https://schema.org",
"@type": "TechArticle",
"@id": "https://support.zendesk.com/hc/en-us/articles/9853782610970",
"url": "https://support.zendesk.com/hc/en-us/articles/9853782610970-Using-custom-code-steps-in-action-flows",
"headline": "Using custom code steps in action flows",
"description": "You can add and configure custom JavaScript code steps in action flows to perform complex data transformations and logic beyond predefined actions, with support for various input and output data types and AI-generated code prompts.",
"articleSection": "Extending Zendesk",
"datePublished": "2025-10-21T17:00:55+00:00",
"dateModified": "2026-02-22T20:09:26+00:00",
"inLanguage": "en-US",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://support.zendesk.com/hc/en-us/articles/9853782610970"
},
"author": {
"@type": "Organization",
"name": "Zendesk",
"@id": "https://www.zendesk.com"
},
"publisher": {
"@type": "Organization",
"name": "Zendesk",
"@id": "https://www.zendesk.com"
},
"isPartOf": {
"@type": "WebSite",
"name": "Zendesk Help",
"@id": "https://support.zendesk.com/hc/"
},
"about": {
"@type": "SoftwareApplication",
"name": "Zendesk",
"@id": "https://www.zendesk.com"
}
}</script>