diff --git a/content/applications/studio/automated_actions.rst b/content/applications/studio/automated_actions.rst index f407a3dec..f8013901d 100644 --- a/content/applications/studio/automated_actions.rst +++ b/content/applications/studio/automated_actions.rst @@ -1,249 +1,343 @@ -=============================== -Automated actions (automations) -=============================== +================ +Automation rules +================ -Automated actions are used to trigger automatic changes based on user actions (e.g., apply a -modification when a field is set to a specific value) or on time conditions (e.g., archive a record -7 days after its last update). +Automation rules are used to trigger automatic changes based on user actions (e.g., apply a +modification when a field is set to a specific value), email events, time conditions (e.g., archive +a record 7 days after its last update), or external events. -To create an automated action with Studio, go to :guilabel:`Automations` from anywhere within -Studio. +To create an automation rule with Studio, proceed as follows: -For every automated action you create, the following elements should be defined: the -:ref:`studio/automated-actions/model`, the :ref:`studio/automated-actions/trigger`, the -:ref:`studio/automated-actions/apply-on`, and the :ref:`studio/automated-actions/action`. +#. Open Studio and click :guilabel:`Automations`, then :guilabel:`New`. +#. Select the :ref:`studio/automated-actions/trigger` and, if necessary, fill in the fields that + appear on the screen based on the chosen trigger. +#. Click :guilabel:`Add an action`, then select the :guilabel:`Type` of + :ref:`action ` and fill in the fields that appear on the screen + based on your selected action. +#. Click :guilabel:`Save & Close` or :guilabel:`Save & New`. .. example:: - .. image:: automated_actions/automated-action-example.png - :align: center + .. image:: automated_actions/automation-rule-ex.png :alt: Example of an automated action on the Subscription model -.. _studio/automated-actions/model: +.. tip:: + - To modify the :doc:`model ` of the automation rule, switch models before + clicking :guilabel:`Automations` in Studio, or :ref:`activate the developer mode + `, create or edit an automation rule, and select the :guilabel:`Model` in the + :guilabel:`Automation Rules` form. + - You can also create automation rules from any kanban stage by clicking the gear icon + (:guilabel:`⚙` ) next to the kanban stage name, then selecting :guilabel:`Automations`. In this + case, the :guilabel:`Trigger` is set to :guilabel:`Stage is set to` by default, but you can + change it if necessary. -Model -===== - -Select the model where the automated action should be applied. - -.. note:: - The model you are on when you click on :guilabel:`Automations` is pre-selected by default. + .. image:: automated_actions/automations-kanban.png + :alt: Create automations from a kanban stage .. _studio/automated-actions/trigger: Trigger ======= -Define when the automated action should be applied. Six triggers are available. +The :guilabel:`Trigger` is used to define when the automation rule should be applied. The available +triggers depend on the :doc:`model `. Five trigger categories are available +overall: -.. _studio/automated-actions/trigger/on-creation: +- :ref:`studio/automated-actions/trigger/values-updated` +- :ref:`studio/automated-actions/trigger/email-events` +- :ref:`studio/automated-actions/trigger/values-timing-conditions` +- :ref:`studio/automated-actions/trigger/custom` +- :ref:`studio/automated-actions/trigger/external` -On Creation ------------ +.. tip:: + You can also define a :guilabel:`Before Update Domain` to specify the conditions that must be met + *before* the automation rule is triggered. In contrast, the conditions defined using the + :ref:`Extra Conditions ` and + :ref:`Apply on ` filters are checked *during* the + execution of the automation rule. -The action is triggered when a record is created and then saved. + To define a :guilabel:`Before Update Domain`, :ref:`activate the developer mode + `, create or edit an automation rule, click :guilabel:`Edit Domain`, then click + :guilabel:`New Rule`. -.. _studio/automated-actions/trigger/on-update: + For example, if you want the automated action to happen when an email address is set on a + contact that did not have an address before (in contrast to modifying their existing address), + define the :guilabel:`Before Update Domain` to :guilabel:`Email is not set`, and the + :guilabel:`Apply on` domain to :guilabel:`Email is set`. -On Update ---------- + .. image:: automated_actions/before-update-domain.png + :alt: Example of a trigger with a Before Update Domain -The action is triggered when a previously saved record is edited and then saved. +.. _studio/automated-actions/trigger/values-updated: -- Use :guilabel:`Trigger Fields` to specify which fields - and only those - trigger the action on - their update. -- To detect when a record changes from one state to another, define a :guilabel:`Before Update - Domain` filter, which checks if the condition is satisfied before the record is updated. Then set - an :ref:`studio/automated-actions/apply-on` filter, which checks if the condition is met after the - record is updated. +Values Updated +-------------- - .. example:: - If you want the automated action to happen when an email address is set on a contact, define - the :guilabel:`Before Update Domain` to `Email is not set`, and the :guilabel:`Apply on` - domain to `Email is set`. +The triggers available in this category depend on the model and are based on common field changes, +such as adding a specific tag (e.g., to a task) or setting the :guilabel:`User` field. Select the +trigger, then select a value if required. - .. image:: automated_actions/on-update-trigger-example.png - :align: center - :alt: Example of an On Update trigger +.. image:: automated_actions/values-updated-trigger.png + :alt: Example of a Values Updated trigger -.. _studio/automated-actions/trigger/on-creation-update: +.. _studio/automated-actions/trigger/email-events: -On Creation & Update --------------------- +Email Events +------------ -The action is triggered when a record is created and saved or edited afterward and saved. +Trigger automated actions upon receiving or sending emails. -.. _studio/automated-actions/trigger/on-deletion: +.. _studio/automated-actions/trigger/values-timing-conditions: -On Deletion ------------ +Timing Conditions +----------------- -The action is triggered when a record is deleted. +Trigger automated actions based on a date field. The following triggers are available: + +- :guilabel:`Based on date field`: Select the field to be used next to the :guilabel:`Delay` field. +- :guilabel:`After creation`: The action is triggered when a record is created and saved. +- :guilabel:`After last update`: The action is triggered when an existing record is edited and + saved. + +You can then define: + +- a :guilabel:`Delay`: Specify the number of minutes, hours, days, or months. To trigger the action + before the trigger date, specify a negative number. If you selected the :guilabel:`Based on date + field` trigger, you must also select the date field to be used to determine the delay. +- :guilabel:`Extra Conditions`: Click :guilabel:`Add condition`, then specify the conditions to be + met to trigger the automation rule. Click :guilabel:`New Rule` to add another condition. + +The action is triggered when the delay is reached and the conditions are met. + +.. example:: + If you want to send a reminder email 30 minutes before the start of a calendar event, select the + :guilabel:`Start (Calendar Event)` under :guilabel:`Trigger Date` and set the :guilabel:`Delay` + to **-30** :guilabel:`Minutes`. + + .. image:: automated_actions/timing-conditions-trigger.png + :alt: Example of a Based on date field trigger .. note:: - This trigger is rarely used, as archiving records is usually preferred to deletion. + By default, the scheduler checks for trigger dates every 4 hours, meaning lower granularity in + time-based automations may not always be honored. -.. _studio/automated-actions/trigger/form-modification: +.. _studio/automated-actions/trigger/custom: -Based on Form Modification --------------------------- +Custom +------ -The action is triggered when any change is done to a trigger field's value on the :ref:`Form view -`, even before saving the record. This trigger only works on the user -interface when a modification is made by a user. If the field is changed through another action and -not by the user, the action will not run. +Trigger automated actions: + +- :guilabel:`On save`: When the record is saved; +- :guilabel:`On deletion`: When a record is deleted; +- :guilabel:`On UI change`: When a field's value is changed on the :ref:`Form view + `, even before saving the record. + +For the :guilabel:`On save` and :guilabel:`On UI change` triggers, you **must** then select the +field(s) to be used to trigger the automation rule in the :guilabel:`When updating` field. + +.. warning:: + If no field is selected in the :guilabel:`When updating` field, the automated action may be + executed multiple times per record. + +Optionally, you can also define additional conditions to be met to trigger the automation rule in +the :guilabel:`Apply on` field. .. note:: - This trigger can only be used with the :ref:`Execute Python Code action - `, so development is required. + The :guilabel:`On UI change` trigger can only be used with the + :ref:`studio/automated-actions/action/python-code` action and only works when a modification is + made manually. The action is not executed if the field is changed through another automation + rule. -.. _studio/automated-actions/trigger/timed-condition: +.. _studio/automated-actions/trigger/external: -Based on Timed Condition ------------------------- +External +-------- -The action is triggered when a trigger field's date or date & time value is reached. +Trigger automated actions based on an external event using a webhook. A webhook is a method of +communication between two systems where the source system sends an HTTP(S) request to a destination +system based on a specific event. It usually includes a data payload containing information about +the event that occurred. -- To trigger the action after the :guilabel:`Trigger Date`, add a number of minutes, hours, days, or - months under :guilabel:`Delay after trigger date`. To trigger the action before, add a negative - number instead. +To configure the :guilabel:`On webhook` trigger, copy the :guilabel:`URL` generated by Odoo into the +destination system (i.e., the system receiving the request). Then, in the :guilabel:`Target Record` +field, enter the code to run to define the record(s) to be updated using the automation rule. - .. example:: - If you want to send a reminder email 30 minutes before the start of a calendar event, select - the :guilabel:`Start (Calendar Event)` under :guilabel:`Trigger Date` and set the - :guilabel:`Delay after trigger date` to **-30** :guilabel:`Minutes`. - - .. image:: automated_actions/timed-condition-trigger-example.png - :align: center - :alt: Example of a Based on Timed Condition trigger +.. warning:: + The URL must be treated as **confidential**; sharing it online or without caution could + potentially expose your system to malicious parties. Click the :guilabel:`Rotate Secret` button + to change the URL's secret if necessary. .. note:: - By default, the scheduler checks for trigger dates every 4 hours. + - The code defined by default in the :guilabel:`Target Record` field works for webhooks coming + from another Odoo database. It is used to determine the record(s) to be updated using the + information in the payload. + - If you wish to use the webhook's content for a purpose other than to find the record(s) (e.g., + *create* a record), your only option is to use an :ref:`studio/automated-actions/action/python-code` + action. In this case, the :guilabel:`Target record` field must contain any valid code, but its + result doesn't have any effect on the automated action itself. + - The webhook content is available in the server action context as a `payload` variable (i.e., a + dictionary that contains the GET parameters or POST JSON body of the incoming request). -.. _studio/automated-actions/apply-on: - -Apply on -======== - -Define on which records of the model the automated action should be applied. It works the same way -as when you apply filters on a model. +You can also choose to :guilabel:`Log Calls` to record the payloads received, e.g., to make sure the +data sent by the source system matches the expected format and content. This also helps identify +and diagnose any issues that may arise. To access the logs, click the :guilabel:`Logs` smart +button at the top of the :guilabel:`Automation rules` form. .. _studio/automated-actions/action: -Action -====== +Actions +======= -Determine what the automated action should do (server action). There are eight types of action to -choose from. +Once you have defined the automation rule's :ref:`trigger `, click +:guilabel:`Add an action` to define the action to be executed. -.. _studio/automated-actions/action/python-code: - -Execute Python Code -------------------- - -The action is used to execute Python code. The available variables are described on the -:guilabel:`Python Code` tab, which is also used to write your code, or on the :guilabel:`Help` tab. - -- To allow the action to be run through the website, tick :guilabel:`Available on the Website` and - add a :guilabel:`Website Path`. - -.. _studio/automated-actions/action/new-record: - -Create a new Record -------------------- - -The action is used to create a new record on any model. - -.. note:: - Selecting a :guilabel:`Target Model` is only required if you want to target another model than - the one you are on. - -- To link the record that triggered the creation of the new record, select a field under - :guilabel:`Link Field`. For example, you could create a contact automatically when a lead is - turned into an opportunity. -- :guilabel:`Data to Write` tab: the tab is used to specify the new record's values. After selecting - a :guilabel:`Field`, select its :guilabel:`Evaluation Type`: - - - :guilabel:`Value`: used to directly give the field's raw value in the :guilabel:`Value` column. - - :guilabel:`Reference`: used to select the record under the :guilabel:`Record` column and let - Studio add the internal ID in the :guilabel:`Value` column. - - .. example:: - If an automated action creates a new task in a project, you can assign it to a specific user - by setting the :guilabel:`Field` to :guilabel:`Responsible User (Project)`, the - :guilabel:`Evaluation Type` to :guilabel:`Reference`, and the :guilabel:`Record` to a - specific user. - - .. image:: automated_actions/new-record-example.png - :align: center - :alt: Example of a Create a new Record action - - - :guilabel:`Python expression`: used to dynamically define the newly created record’s value for a - field using Python code in the :guilabel:`Value` column. +.. tip:: + You can define multiple actions for the same trigger/automation rule. The actions are executed + in the order they are defined. This means, for example, that if you define an + :guilabel:`Update record` action and then a :guilabel:`Send email` action, the email uses the + updated values. However, if the :guilabel:`Send email` action is defined before the + :guilabel:`Update record` action, the email uses the values set *before* the update action is + run. .. _studio/automated-actions/action/update-record: -Update the Record ------------------ +Update Record +------------- -The action is used to set value(s) for field(s) of any record on the current model. +This action allows to update one of the record's (related) fields. Click the :guilabel:`Update` +field and, in the list that opens, select or search for the field to be updated; click the right +arrow next to the field name to access the list of related fields if needed. -.. note:: - The process to fill in the :guilabel:`Data to Write` tab is the same as described under - :ref:`studio/automated-actions/action/new-record`. +If you selected a :ref:`many2many field `, choose whether +the field must be updated by :guilabel:`Adding`, :guilabel:`Removing`, or :guilabel:`Setting it to` +the selected value or by :guilabel:`Clearing it`. -.. _studio/automated-actions/action/several-actions: +.. example:: + If you want the automated action to remove a tag from the customer record, set the + :guilabel:`Update` field to :guilabel:`Customer > Tags`, select :guilabel:`By Removing`, then + select the tag. -Execute several actions + .. image:: automated_actions/update-record-action.png + :alt: Example of an Update Record action + +.. tip:: + Alternatively, you can also set a record's field dynamically using Python code. To do so, select + :guilabel:`Compute` instead of :guilabel:`Update`, then enter the code to be used for computing + the field's value. For example, if you want the automation rule to compute a custom + :ref:`datetime field ` when a task's priority is set to + `High` (by starring the task), you can define the trigger :guilabel:`Priority is set to` to + `High` and define the :guilabel:`Update Record` action as follows: + + .. image:: automated_actions/update-record-compute.png + :alt: Compute a custom datetime field using a Python expression + +Create Activity +--------------- + +This action is used to schedule a new activity linked to the record. Select an :guilabel:`Activity +Type`, enter a :guilabel:`Title` and description, then specify when you want the activity to be +scheduled in the :guilabel:`Due Date In` field, and select a :guilabel:`User type`: + +- To always assign the activity to the same user, select :guilabel:`Specific User` and add the user + in the :guilabel:`Responsible` field; +- To target a user linked to the record dynamically, select :guilabel:`Dynamic User (based on + record)` and change the :guilabel:`User Field` if necessary. + +.. example:: + After a lead is turned into an opportunity, you want the automated action to set up a call for + the user responsible for the lead. To do so, set the :guilabel:`Activity Type` to + :guilabel:`Call` and the :guilabel:`User Type` to :guilabel:`Dynamic User (based on record)`. + + .. image:: automated_actions/create-activity-action.png + :alt: Example of a Create Activity action + +Send Email and Send SMS ----------------------- -The action is used to trigger multiple actions at the same time. To do so, click on :guilabel:`Add a -line` under the :guilabel:`Actions` tab. In the :guilabel:`Child Actions` pop-up, click on -:guilabel:`Create` and configure the action. +These actions are used to send an email or a text message to a contact linked to a specific record. +To do so, select or create an :guilabel:`Email Template` or an :guilabel:`SMS Template`, then, in +the :guilabel:`Send Email As` or :guilabel:`Send SMS As` field, choose how you want to send the +email or text message: -.. _studio/automated-actions/action/send-email: - -Send Email ----------- - -The action is used to send an email to a contact linked to a specific record. To do so, select or -create an :guilabel:`Email Template`. +- :guilabel:`Email`: to send the message as an email to the recipients of the :guilabel:`Email + Template`. +- :guilabel:`Message`: to post the message on the record and notify the record's followers. +- :guilabel:`Note`: to send the message as an internal note visible to internal users in the + chatter. +- :guilabel:`SMS (without note)`: to send the message as a text message to the recipients of the + :guilabel:`SMS template`. +- :guilabel:`SMS (with note)`: to send the message as a text message to the recipients of the + :guilabel:`SMS template` and post it as an internal note in the chatter. +- :guilabel:`Note only`: to only post the message as an internal note in the chatter. .. _studio/automated-actions/action/add-followers: -Add Followers +Add Followers and Remove Followers +---------------------------------- + +Use these actions to (un)subscribe existing contacts to/from the record. + +Create Record ------------- -The action is used to subscribe existing contacts to the record. +This action is used to create a new record on any model. -.. _studio/automated-actions/action/next-activity: +Select the required model in the :guilabel:`Record to Create` field; it contains the current model +by default. Specify a :guilabel:`Name` for the record, and then, if you want to create the record on +another model, select a field in the :guilabel:`Link Field` field to link the record that +triggered the creation of the new record. -Create Next Activity --------------------- - -The action is used to schedule a new activity linked to the record. Use the :guilabel:`Activity` tab -to set it up as usual, but instead of the :guilabel:`Assigned to` field, select an -:guilabel:`Activity User Type`. Select :guilabel:`Specific User` and add the user under -:guilabel:`Responsible` if the activity should always be assigned to the same user. To dynamically -target a user linked to the record, select :guilabel:`Generic User From Record` instead and change -the :guilabel:`User field name` if necessary. - -.. example:: - After a lead is turned into an opportunity, you want your automated action to set up a call for - the user responsible for the lead. To do so, set the :guilabel:`Activity` to :guilabel:`Call` - and set the :guilabel:`Activity User Type` to :guilabel:`Generic User From Record`. - - .. image:: automated_actions/next-activity-example.png - :align: center - :alt: Example of a Create Next Activity action - -.. _studio/automated-actions/action/send-sms: - -Send SMS Text Message ---------------------- - -The action is used to send an SMS to a contact linked to the record. To do so, select or create an -:guilabel:`SMS Template`. +.. note:: + The dropdown list related to the :guilabel:`Link Field` field only contains :ref:`one2many fields + ` existing on the current model that are linked to a + :ref:`many2one field ` on the target model. .. tip:: - If you want sent messages to be logged in the Chatter, tick :guilabel:`Log as Note`. + You can create another automation rule with :ref:`studio/automated-actions/action/update-record` + actions to update the fields of the new record if necessary. For example, you can use a + :guilabel:`Create Record` action to create a new project task and then assign it to a specific + user using an :guilabel:`Update Record` action. + +.. _studio/automated-actions/action/python-code: + +Execute Code +------------ + +This action is used to execute Python code. You can write your code into the :guilabel:`Code` tab +using the following variables: + +- `env`: environment on which the action is triggered +- `model`: model of the record on which the action is triggered; is a void recordset +- `record`: record on which the action is triggered; may be void +- `records`: recordset of all records on which the action is triggered in multi-mode; this may be + left empty +- `time`, `datetime`, `dateutil`, `timezone`: useful Python libraries +- `float_compare`: utility function to compare floats based on specific precision +- `log(message, level='info')`: logging function to record debug information in ir.logging + table +- `_logger.info(message)`: logger to emit messages in server logs +- `UserError`: exception class for raising user-facing warning messages +- `Command`: x2many commands namespace +- `action = {...}`: to return an action + +.. tip:: + The available variables are described both in the :guilabel:`Code` and :guilabel:`Help` tabs. + +Send Webhook Notification +------------------------- + +This action allows to send a POST request with the values of the :guilabel:`Fields` to the URL +specified in the :guilabel:`URL` field. + +The :guilabel:`Sample Payload` provides a preview of the data included in the request using a random +record's data or dummy data if no record is available. + +.. _studio/automated-actions/action/several-actions: + +Execute Existing Actions +------------------------ + +The action is used to trigger multiple actions (linked to the current model) at the same time. To do +so, click on :guilabel:`Add a line`, then, in the :guilabel:`Add: Child Actions` pop-up, select an +existing action or click :guilabel:`New` to create a new one. diff --git a/content/applications/studio/automated_actions/automated-action-example.png b/content/applications/studio/automated_actions/automated-action-example.png deleted file mode 100644 index 9e3bb6616..000000000 Binary files a/content/applications/studio/automated_actions/automated-action-example.png and /dev/null differ diff --git a/content/applications/studio/automated_actions/automation-rule-ex.png b/content/applications/studio/automated_actions/automation-rule-ex.png new file mode 100644 index 000000000..221bb156c Binary files /dev/null and b/content/applications/studio/automated_actions/automation-rule-ex.png differ diff --git a/content/applications/studio/automated_actions/automations-kanban.png b/content/applications/studio/automated_actions/automations-kanban.png new file mode 100644 index 000000000..cad1db62f Binary files /dev/null and b/content/applications/studio/automated_actions/automations-kanban.png differ diff --git a/content/applications/studio/automated_actions/before-update-domain.png b/content/applications/studio/automated_actions/before-update-domain.png new file mode 100644 index 000000000..a775c6159 Binary files /dev/null and b/content/applications/studio/automated_actions/before-update-domain.png differ diff --git a/content/applications/studio/automated_actions/create-activity-action.png b/content/applications/studio/automated_actions/create-activity-action.png new file mode 100644 index 000000000..cc6e2f42d Binary files /dev/null and b/content/applications/studio/automated_actions/create-activity-action.png differ diff --git a/content/applications/studio/automated_actions/new-record-example.png b/content/applications/studio/automated_actions/new-record-example.png deleted file mode 100644 index 76deb7f5a..000000000 Binary files a/content/applications/studio/automated_actions/new-record-example.png and /dev/null differ diff --git a/content/applications/studio/automated_actions/next-activity-example.png b/content/applications/studio/automated_actions/next-activity-example.png deleted file mode 100644 index 82ae712eb..000000000 Binary files a/content/applications/studio/automated_actions/next-activity-example.png and /dev/null differ diff --git a/content/applications/studio/automated_actions/on-update-trigger-example.png b/content/applications/studio/automated_actions/on-update-trigger-example.png deleted file mode 100644 index da85410cf..000000000 Binary files a/content/applications/studio/automated_actions/on-update-trigger-example.png and /dev/null differ diff --git a/content/applications/studio/automated_actions/timed-condition-trigger-example.png b/content/applications/studio/automated_actions/timed-condition-trigger-example.png deleted file mode 100644 index 07019195c..000000000 Binary files a/content/applications/studio/automated_actions/timed-condition-trigger-example.png and /dev/null differ diff --git a/content/applications/studio/automated_actions/timing-conditions-trigger.png b/content/applications/studio/automated_actions/timing-conditions-trigger.png new file mode 100644 index 000000000..41ca2575d Binary files /dev/null and b/content/applications/studio/automated_actions/timing-conditions-trigger.png differ diff --git a/content/applications/studio/automated_actions/update-record-action.png b/content/applications/studio/automated_actions/update-record-action.png new file mode 100644 index 000000000..1915eef21 Binary files /dev/null and b/content/applications/studio/automated_actions/update-record-action.png differ diff --git a/content/applications/studio/automated_actions/update-record-compute.png b/content/applications/studio/automated_actions/update-record-compute.png new file mode 100644 index 000000000..c0c812912 Binary files /dev/null and b/content/applications/studio/automated_actions/update-record-compute.png differ diff --git a/content/applications/studio/automated_actions/values-updated-trigger.png b/content/applications/studio/automated_actions/values-updated-trigger.png new file mode 100644 index 000000000..39758f705 Binary files /dev/null and b/content/applications/studio/automated_actions/values-updated-trigger.png differ