Skip to content

Automations (Preview)

Warning

This feature is currently under development, and its final scope and capabilities have yet to be determined. The information provided here is subject to change.

Automations can be enabled with the run_automations feature switch.

Automations is the perfect tool when you want something to happen automatically. Automations requires no coding and are created in a visual point-and-click tool.

Examples of Automations:

  • Create a "status change" when a deal is closed.
  • Send notifications upon work order assignment.
  • Enroll a lead into an automated flow upon creation.
  • Record a timestamp when a ticket is closed.

These can be conceptualized as "WHEN an event occurs, THEN execute the following actions." Automations break down these processes into triggers and steps:

WHEN: [Trigger occurs]
THEN: [Execute Step1], [Execute Step2], [Execute Step3], ...

The steps are picked from a list of available steps, which we call The Step Library. This library covers the most common needs such as creating and updating objects. For more complex Automations, multiple steps may be necessary.

To refine execution, steps can include prerequisite conditions, akin to if-statements, ensuring that only relevant actions are taken:

WHEN: [Trigger occurs]
THEN: IF [condition1] { Execute Step1 }, IF [condition2] { Execute Step2 }, IF [condition3] { Execute Step3 }, ...

Getting started:

Go to Lime Admin -> System -> Automations.

There you will find:

  • A visual automation builder
  • Logs from all previously run Automations

Triggers

Triggers define the WHEN part of an Automation. The only available trigger is "Lime object is being created or updated", applicable to various scenarios such as winning a deal, closing a ticket, or creating a lead.

Lime object is being created or updated

Automations with this triggers happens when saving changes. If an automation fails it will prevent the entire save from going through.

This trigger will only run automations for those lime objects that was in the original save. This means lime objects created or updated in an automation will not trigger automations for those other objects!

For example, let says we have two automations:

  • WHEN a deal is closed and the associated company isn't an customer THEN update associated company to be a customer
  • WHEN a company becomes a customer THEN send an email to the billing department

Then if a user closes a deal the company will become a customer but there will be no email sent.

Future triggers (Not available in preview)

The automations preview only contains one trigger, the feature however is designed with many more in mind. Including:

  • Lime object has been created or updated: Runs automations in the event handler. Sometimes this is preferable to be sure the originating change has been persisted to the database and other times its just to be able to run steps that takes longer to complete (like calling an external system).

  • User clicks an action in the web client: Today adding a new custom action to the web client requires both a custom command and a custom endpoint. Using a "standard automation action" this could be done without writing any code.

Step Library

The THEN part of an Automation consists of various steps available in the Step Library. These include creating new lime objects, calculating formulas, and updating fields.

Create new

This step creates new lime objects, for example status change, history or participant. This is used for cases such as "When a Deal changes status, create a Status Change Note about this" or "When a Lead is created, add this Lead as a Participant to a specific Automated Flow"

Update fields

This step updates one or more fields on a lime object. Typical use cases are "When a Deal is won or lost, set the Deal's Closed/Won Date to Today's date" or "When a Deal is updated, calculate the Weighted Value and save it to the field Weighted value."

Get lime object

This step loads a lime object for a given lime type and record ID and provides it as output from the step. This object can then be used later on in the automation. For example load the object "Invoice question" and then use its output to Set the ticket type on the ticket to "Invoice Question"

Formula

This step offers a kind of script language called Jinja. It can be used to for example format phone numbers, capitalize strings or do arithmetics. At first glance Jinja can be daunting but most users will only need to learn a subset.

The lime object that triggers the automation is available as the variable event.limeobject and the formatting-filters found in Document Templates can also be used here.

Examples:

  • Concatenate firstname and lastname when updating a coworker:

    {{event.limeobject.firstname}} {{event.limeobject.lastname}}
    
  • Get tomorrow's date:

    {{context.today | add_days(1)}}
    
  • Compute the weighted value of a deal:

    {{event.limeobject.value * event.limeobject.probability}}
    
  • Format a phone numer:

    {% for letter in event.limeobject.mobilephone %}{% if letter in '+0123456789' %}{{letter}}{% endif %}{% endfor %}
    
  • Create a good note (in markdown) to be used in a status change note when closing a Deal:

    {{context.active_user.name}} closed deal **{{event.limeobject.name}}**
    on company {{event.limeobject.company.name}} for 
    **{{event.limobject.value | format_number(locale="sv_SE", decimal_places=2)}} SEK**.
    

Refer to the Document Templates' documentation and the official Jinja documentation for more filter examples.

Sample automations

To use one of the examples in your own application follow these steps:

  1. Copy the json from one of the examples below (there is a copy button)
  2. Go to "Lime Admin -> System -> Automations"
  3. Click the "+ automation" button
  4. Switch to "code editor"
  5. Paste in the json
  6. Switch back from "code editor"

Use this to create a history note when a company becomes a customer.

Create history when company becomes customer
{
  "id": "fdf0b870-6df2-4241-842a-a80d5fbf5c47",
  "title": "Company: New Customer",
  "active": true,
  "steps": [
    {
      "id": "step1",
      "title": "Create history for new customer",
      "action": "create_limeobject",
      "arguments": {
        "limetype": {
          "exp_type": "constant",
          "value": "history"
        },
        "properties": {
          "exp_type": "map",
          "items": [
            {
              "key": {
                "exp_type": "constant",
                "value": "note"
              },
              "value": {
                "exp_type": "constant",
                "value": "Became a customer!"
              }
            },
            {
              "key": {
                "exp_type": "constant",
                "value": "type"
              },
              "value": {
                "exp_type": "constant",
                "value": "comment"
              }
            },
            {
              "key": {
                "exp_type": "constant",
                "value": "company"
              },
              "value": {
                "exp_type": "context",
                "key": "event.limeobject"
              }
            },
            {
              "key": {
                "exp_type": "constant",
                "value": "coworker"
              },
              "value": {
                "exp_type": "context",
                "key": "context.active_user"
              }
            }
          ]
        }
      },
      "condition": {
        "exp_type": "and",
        "expressions": [
          {
            "exp_type": "or",
            "expressions": [
              {
                "exp_type": "has_changed",
                "limeobject": {
                  "exp_type": "context",
                  "key": "event.limeobject"
                },
                "property_name": {
                  "exp_type": "constant",
                  "value": "buyingstatus"
                }
              }
            ]
          },
          {
            "exp_type": "or",
            "expressions": [
              {
                "exp_type": "equals",
                "left": {
                  "exp_type": "context",
                  "key": "event.limeobject.buyingstatus.key"
                },
                "right": {
                  "exp_type": "constant",
                  "value": "active"
                }
              }
            ]
          }
        ]
      }
    }
  ],
  "trigger": {
    "limeType": "company",
    "triggerType": "limeobject",
    "onUpdate": true,
    "onCreate": true
  }
}

Use this automation to timestamp when a deal is won or lost.

Deal order/lost date
{
  "id": "eb844c9d-76f2-4c51-809a-3a8315faf550",
  "title": "Deal: Order/lost date",
  "active": true,
  "steps": [
    {
      "id": "step1",
      "title": "Set order/lost date",
      "action": "update_limeobject",
      "arguments": {
        "limeobject": {
          "exp_type": "context",
          "key": "event.limeobject"
        },
        "properties": {
          "exp_type": "map",
          "items": [
            {
              "key": {
                "exp_type": "constant",
                "value": "closeddate"
              },
              "value": {
                "exp_type": "context",
                "key": "context.now"
              }
            }
          ]
        }
      },
      "condition": {
        "exp_type": "and",
        "expressions": [
          {
            "exp_type": "or",
            "expressions": [
              {
                "exp_type": "is_empty",
                "expression": {
                  "exp_type": "context",
                  "key": "event.limeobject.closeddate"
                }
              }
            ]
          },
          {
            "exp_type": "or",
            "expressions": [
              {
                "exp_type": "equals",
                "left": {
                  "exp_type": "context",
                  "key": "event.limeobject.dealstatus.key"
                },
                "right": {
                  "exp_type": "constant",
                  "value": "agreement"
                }
              },
              {
                "exp_type": "equals",
                "left": {
                  "exp_type": "context",
                  "key": "event.limeobject.dealstatus.key"
                },
                "right": {
                  "exp_type": "constant",
                  "value": "rejection"
                }
              }
            ]
          }
        ]
      }
    }
  ],
  "trigger": {
    "limeType": "deal",
    "triggerType": "limeobject",
    "onUpdate": true,
    "onCreate": true
  }
}

Use this automation to calculate the weighted value on a deal.

The weighted value is the potential deal value multiplied with the probability of closing the deal.

Weighted value on deal
{
  "id": "ef8aa034-04bf-4d4c-aff3-247439695260",
  "title": "Deal: Weighted Value",
  "active": true,
  "steps": [
    {
      "id": "step1",
      "title": "If lost, probability is 0%",
      "action": "update_limeobject",
      "arguments": {
        "limeobject": {
          "exp_type": "context",
          "key": "event.limeobject"
        },
        "properties": {
          "exp_type": "map",
          "items": [
            {
              "key": {
                "exp_type": "constant",
                "value": "probability"
              },
              "value": {
                "exp_type": "constant",
                "value": 0
              }
            }
          ]
        }
      },
      "condition": {
        "expressions": [
          {
            "expressions": [
              {
                "left": {
                  "key": "event.limeobject.dealstatus.key",
                  "fallback": null,
                  "exp_type": "context"
                },
                "right": {
                  "value": "rejection",
                  "exp_type": "constant"
                },
                "exp_type": "equals"
              }
            ],
            "exp_type": "or"
          }
        ],
        "exp_type": "and"
      }
    },
    {
      "id": "step2",
      "title": "If won, probability is 100%",
      "action": "update_limeobject",
      "arguments": {
        "limeobject": {
          "exp_type": "context",
          "key": "event.limeobject"
        },
        "properties": {
          "exp_type": "map",
          "items": [
            {
              "key": {
                "exp_type": "constant",
                "value": "probability"
              },
              "value": {
                "exp_type": "constant",
                "value": 1
              }
            }
          ]
        }
      },
      "condition": {
        "expressions": [
          {
            "expressions": [
              {
                "left": {
                  "key": "event.limeobject.dealstatus.key",
                  "fallback": null,
                  "exp_type": "context"
                },
                "right": {
                  "value": "agreement",
                  "exp_type": "constant"
                },
                "exp_type": "equals"
              }
            ],
            "exp_type": "or"
          }
        ],
        "exp_type": "and"
      }
    },
    {
      "id": "step3",
      "title": "Calculate weighted value",
      "action": "formula",
      "arguments": {
        "template": {
          "value": "{{event.limeobject.value*event.limeobject.probability}}",
          "exp_type": "constant"
        }
      },
      "condition": null
    },
    {
      "id": "step4",
      "title": "Update deal with the new weighted value",
      "action": "update_limeobject",
      "arguments": {
        "limeobject": {
          "exp_type": "context",
          "key": "event.limeobject"
        },
        "properties": {
          "exp_type": "map",
          "items": [
            {
              "key": {
                "exp_type": "constant",
                "value": "weightedvalue"
              },
              "value": {
                "exp_type": "context",
                "key": "steps.step3.output.value"
              }
            }
          ]
        }
      },
      "condition": null
    }
  ],
  "trigger": {
    "limeType": "deal",
    "triggerType": "limeobject",
    "onUpdate": true,
    "onCreate": true
  }
}

Creates a history note of all protocol answers when a work order is closed.

This example requires the lime types from the Work Order addon.

Summarize work order protocols
{
  "id": "1e2c54c3-e848-490b-933f-4b6f5a6196cc",
  "title": "Work Order: Protocol Summary",
  "active": true,
  "steps": [
    {
      "id": "step1",
      "title": "Summarize protocols",
      "action": "formula",
      "arguments": {
        "template": {
          "value": "{% for form in event.limeobject.limepkg_form_protocol -%}\n📄 **{{form.title}}**:\n{% for answer in form.limepkg_form_answer -%}\n* {{answer.title}}: {{answer.answer}}{% if answer.comment != \"\"%} - *{{answer.comment}}*{%endif%}\n{% endfor %}\n\n{% endfor -%}",
          "exp_type": "constant"
        }
      },
      "condition": {
        "exp_type": "and",
        "expressions": [
          {
            "limeobject": {
              "key": "event.limeobject",
              "fallback": null,
              "exp_type": "context"
            },
            "property_name": {
              "value": "state",
              "exp_type": "constant"
            },
            "exp_type": "has_changed"
          },
          {
            "left": {
              "key": "event.limeobject.state.key",
              "fallback": null,
              "exp_type": "context"
            },
            "right": {
              "value": "Finished",
              "exp_type": "constant"
            },
            "exp_type": "equals"
          }
        ]
      }
    },
    {
      "id": "step2",
      "title": "Create protocol summary as history note",
      "action": "create_limeobject",
      "arguments": {
        "limetype": {
          "value": "history",
          "exp_type": "constant"
        },
        "properties": {
          "exp_type": "map",
          "items": [
            {
              "key": {
                "value": "note",
                "exp_type": "constant"
              },
              "value": {
                "key": "steps.step1.output.value",
                "fallback": null,
                "exp_type": "context"
              }
            },
            {
              "key": {
                "value": "workorder",
                "exp_type": "constant"
              },
              "value": {
                "key": "event.limeobject",
                "fallback": null,
                "exp_type": "context"
              }
            },
            {
              "key": {
                "value": "helpdesk",
                "exp_type": "constant"
              },
              "value": {
                "key": "event.limeobject.helpdesk",
                "fallback": null,
                "exp_type": "context"
              }
            },
            {
              "key": {
                "value": "type",
                "exp_type": "constant"
              },
              "value": {
                "value": "comment",
                "exp_type": "constant"
              }
            },
            {
              "key": {
                "exp_type": "constant",
                "value": "coworker"
              },
              "value": {
                "exp_type": "context",
                "key": "context.active_user"
              }
            }
          ]
        }
      },
      "condition": {
        "expressions": [
          {
            "limeobject": {
              "key": "event.limeobject",
              "fallback": null,
              "exp_type": "context"
            },
            "property_name": {
              "value": "state",
              "exp_type": "constant"
            },
            "exp_type": "has_changed"
          },
          {
            "left": {
              "key": "event.limeobject.state.key",
              "fallback": null,
              "exp_type": "context"
            },
            "right": {
              "value": "Finished",
              "exp_type": "constant"
            },
            "exp_type": "equals"
          },
          {
            "expression": {
              "key": "steps.step1.output.value",
              "fallback": null,
              "exp_type": "context"
            },
            "exp_type": "is_not_empty"
          }
        ],
        "exp_type": "and"
      }
    }
  ],
  "trigger": {
    "limeType": "workorder",
    "triggerType": "limeobject",
    "onUpdate": true,
    "onCreate": false
  }
}

FAQ

How fast are automations?

Automations have the same performance impact as you would expect from naive custom lime objects.

Can I create my own custom steps?

There is currently no support for custom steps.

Can I create my own custom triggers?

There is currently no support for custom triggers.

In which order are automations run?

If there are more than one automation that is triggered at the same time the order in which they are run is undefined. If order matters, merge the steps into one automation instead.

How do I move an automation from test to prod?

Automations can be copy-pasted with ease using the "code editor".

How long are automation runs stored?

The automation runs are stored for 7 days. The cleanup is done by lsp_cleanupdb on a nightly schedule.

When will automations be available on-premise?

It depends on the on-premise release schedule, but probably late 2024.

Can I combine custom limeobjects with automations?

There are several ways to customize what happens when something is saved in the system. The following sequence describes how the automation trigger inside the unit of work interacts with those other customization capabilities during saves:

  • When uow.commit() is called:
    1. prepare_update() is called for all custom lime objects in the uow. Any lime objects added to the uow in this step can trigger automations in the next step.
    2. Automations are triggered for all lime objects in the uow. Any lime objects added to the uow in this step will not trigger automations, but may trigger before_update in the next step.
    3. before_update() is called for all custom lime objects in the uow. Any lime objects added to the uow in this step will not trigger any automations.
    4. SQL on UPDATE
    5. after_update() is called for all custom lime objects in the uow.