Skip to main content

Code action

Writing and running your own Python code

Written by Georg Olafsson

When implementing a new workflow, it can be very easy to get stuck on a particular problem that basic actions can not solve. Many of these problems are very niche and are not obvious right away when planning the workflow in advance.

These can be very specific problems, for example:

  • You have an onboarding workflow for a new employee where the requirement is to add information from an Onboarding form to the HR system but the HR system only accepts English letters

  • I receive a "First day of work" date from a supervisor but I need the first working day before that date

  • I received a "Date of birth" from my HR system but I want to know when this persons next birthday is & if it is a big birthday that requires special celebrations

  • I have an integration action that returns a list of items but I only want to use specific items, based on a defined criteria

The list is really endless.


You don't have to know how to code to use the action!

The action comes with a code editor which allows anyone to add / edit code but with our built in AI code generation tool, you can generate new code or update existing with simple prompts.

Here is one example where we add a prompt that gives use the persons next birthday and if it is a big birthday or not, all based on the date of birth of said person (see example below for more details).


So how does it work?

Here is a quick example with an easy employee birthday journey!
​
We have a list of current employees - this can come directly from your HR / Payroll software through an integration or you can import them directly to journeys.

In the workflow, this is the criteria that we have:

  • If the employee has a normal birthday I want to notify the supervisor one day before

  • If the employee has a big birthday I want to notify this persons supervisor two days before and order some flowers

Of course this can have a lot more actions but we will keep it simple for the purpose of demonstration.

We have the journey "ready" but we cannot complete the setup as we are missing the two required pieces of information:

  • When is this persons next birthday

  • Is that birthday a big birthday or normal?

As you can see in the first image above, we only have the date of birth for these individuals so we need to use that in order to find out what we need.

This is where the Code action comes in!

Add the action to the workflow

Now configure the input that the code action will use - in this case it is the Date of Birth

Open the code editor to add or generate the code snippet by AI.

In our case we will use AI with the prompt: "You are given a date of birth for a person, please return the date of this persons next birthday and if that birthday is a big one. This should handle leap years as well."

After the code is generated we are going to test if this will actually work by adding a date of birth to the test functionality. In our test case we see that the action will return the Next birthday date as a "Date" variable and then "If big birthday" as a boolean (true / false).

We can now move on and finish the journey!

First we complete the conditions, check if it is a big birthday (if true, we move on)

And since we have the next birthday date, we can now configure the "Wait until # date" action to pause the journey until 2 days before the birthday.

Complete the same step for the "normal" birthday path and the Journey is now ready!


The code editor

Your code must include one function named process. It should accept whatever inputs you configured and return a dictionary.

Code template:

def process(**kwargs):
"""
Returns:
message (text): Result message
"""
name = kwargs.get("traveller__email", "")
return {
"message": f"Processed for {name}"
}

Rules to remember:

  • The function must be named process.

  • It should use **kwargs so it can receive all the inputs you mapped in the builder.

  • It must return { ... }, which is a dictionary where each key is an output name and each value is the result.

  • Output names should use only letters, numbers, and underscores (e.g. first_name, total_days). Avoid spaces and special characters in names like Bucket ID.


Describing your outputs (the “Returns” section)

At the top of process, add a short description block so the journey knows what each output is and how to show it elsewhere:

"""
Returns:
days_until_start (number): Days until start
start_label (text): Human readable date
"""

For each output line use this pattern:

output_name (type): Short description

Types you can use:

Type

Use for

text

Plain text

email

Email addresses

phone

Phone numbers

date

Dates

number

Whole numbers

decimal

Numbers with decimals

paragraph

Longer text

boolean

Yes/no (true/false)

array

Lists (see below)

array_of_strings

Lists of text lines

select

Single choice values

The output name in this block must match exactly the name you use in return { ... }.


Choosing inputs in the journey builder

In the Code action sidebar, under Input, you map fields from the journey (traveller details, form answers, data from a previous step, etc.).

Each mapped input is passed into process under a specific name.

In your code you read them with:

value = kwargs.get("the_input_name", "")

The code editor lists the exact names available for your journey. Use those names in kwargs.get(...).

Tips:

  • If an input is empty, you’ll usually get an empty string "", not “missing”—so defaults like kwargs.get("name", "") are a good habit.


Tools already available

You cannot add your own import lines or install extra libraries. The following are already available in your code:

Dates and time

  • today() - today’s date

  • parse_date("2024-03-15") - turn a date string into a date you can work with

  • strptime("15/03/2024", "%d/%m/%Y") - parse a date when you know the exact format

  • strftime(some_date, "%Y-%m-%d") — format a date as text

  • datetime - build or adjust dates and times (e.g. add days with timedelta)

  • timedelta - date/time differences (e.g. “7 days from now”)

  • time - work with clocks and timestamps (e.g. time.time() for “seconds since epoch”). Avoid long waits (e.g. time.sleep(...)) because the step only has a few seconds to finish.

Common helpers

  • json - work with JSON-style text (e.g. turn text into structured data with json.loads)

  • re - find or replace patterns in text

  • random - random numbers or choices

  • safe_eval("['a','b']") — safely turn a fixed, literal string into a list or value (only for constants you write in code, not for running arbitrary expressions)

Basic functions

  • abs, min, max, sum, filter, list, dict

Declaration

Return


Update vs Replace

If you are happy with the code that was generated, you can always decide to update that instead of having the action generating new code.

Here you can select which functionality you want

Did this answer your question?