[IMP] studio: updating automation rules and webhooks
Task-4672373
X-original-commit: 199b398eaf
@@ -14,6 +14,8 @@ Odoo Online databases are accessed using any web browser and do not require a lo
|
||||
To quickly try out Odoo, shared `demo <https://demo.odoo.com>`_ instances are available. No
|
||||
registration is required, but each instance only lives for a few hours.
|
||||
|
||||
.. _odoo_online/database-management:
|
||||
|
||||
Database management
|
||||
===================
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ Studio
|
||||
studio/pdf_reports
|
||||
studio/approval_rules
|
||||
|
||||
**Studio** is a toolbox used to customize Odoo without coding knowledge. For example, in any app,
|
||||
add or modify:
|
||||
**Odoo Studio** is a toolbox used to customize Odoo without coding knowledge. For example, in any
|
||||
app, add or modify:
|
||||
|
||||
- :doc:`Fields <studio/fields>`
|
||||
- :doc:`Views <studio/views>`
|
||||
@@ -31,10 +31,22 @@ Learn how to :doc:`build an app from scratch <studio/models_modules_apps>`.
|
||||
|
||||
.. _studio/access:
|
||||
|
||||
To access Studio, navigate to the app and model you want to modify, then click the :icon:`oi-studio`
|
||||
(:guilabel:`Toggle Studio`) icon, or vice versa.
|
||||
To access **Studio**, navigate to the app and model you want to modify, then click the
|
||||
:icon:`oi-studio` (:guilabel:`Toggle Studio`) icon. Alternatively, with any app open, click the
|
||||
:icon:`oi-studio` (:guilabel:`Toggle Studio`) icon and navigate to the relevant app and model.
|
||||
|
||||
To close **Studio**, click :guilabel:`Close` in the upper-right corner.
|
||||
|
||||
.. warning::
|
||||
Installing **Studio** in an Odoo database on the *Standard* pricing plan automatically triggers
|
||||
an upsell to the *Custom* pricing plan.
|
||||
|
||||
- **For yearly or multi-year contracts**: An upsell order is created with a 30-day limit.
|
||||
- **For monthly contracts**: The subscription automatically switches to the *Custom* plan and
|
||||
the new rate is applied when the next bill is generated.
|
||||
|
||||
For more information, refer to `Odoo's pricing page <https://www.odoo.com/pricing-plan>`_ or
|
||||
contact your account manager.
|
||||
|
||||
.. seealso::
|
||||
`Odoo Tutorials: Studio <https://www.odoo.com/slides/studio-31>`_
|
||||
|
||||
@@ -4,34 +4,50 @@
|
||||
Automation rules
|
||||
================
|
||||
|
||||
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.
|
||||
Automation rules allow the execution of one or more predefined actions in response to a specific
|
||||
trigger, e.g., create an activity when a field is set to a specific value, or archive a record 7
|
||||
days after its last update.
|
||||
|
||||
To create an automation rule with Studio, proceed as follows:
|
||||
When creating an automation rule, it is possible to :ref:`add conditions that must be met
|
||||
<studio/automated-actions/conditions>` for the automation rule to run, e.g., the opportunity must be
|
||||
assigned to a specific salesperson, or the state of the record must not be :guilabel:`Draft`.
|
||||
|
||||
To create an automation rule with **Odoo Studio**:
|
||||
|
||||
#. :ref:`Open Studio <studio/access>` 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 <studio/automated-actions/action>` and fill in the fields that appear on the screen
|
||||
based on your selected action.
|
||||
#. Click :guilabel:`Save & Close` or :guilabel:`Save & New`.
|
||||
#. Give the automation rule a clear, meaningful name that identifies its purpose.
|
||||
#. Select the :ref:`Trigger <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` in the :guilabel:`Actions To Do` tab.
|
||||
|
||||
.. tip::
|
||||
If no explicit name is entered, the name of the action will be automatically generated based
|
||||
on the action you define; the name can be updated at any time.
|
||||
|
||||
#. Select the :guilabel:`Type` of :ref:`action <studio/automated-actions/action>` and complete the
|
||||
relevant fields based on the chosen action.
|
||||
#. Click :guilabel:`Save & Close` or, to define additional actions, :guilabel:`Save & New`.
|
||||
|
||||
.. example::
|
||||
|
||||
.. image:: automated_actions/automation-rule-ex.png
|
||||
:alt: Example of an automated action on the Subscription model
|
||||
To ensure follow-up on less satisfied clients, this automation rule creates an activity 3 months
|
||||
after a sales order is created for clients with a satisfaction percentage lower than 30%.
|
||||
|
||||
.. image:: automated_actions/trigger-timing-conditions.png
|
||||
:alt: Example of an automation rule on the Subscription model
|
||||
:scale: 90%
|
||||
|
||||
.. tip::
|
||||
- To modify the :doc:`model <models_modules_apps>` of the automation rule, switch models before
|
||||
clicking :guilabel:`Automations` in Studio, or :ref:`activate the developer mode
|
||||
- Use the :guilabel:`Notes` tab to document the purpose and functioning of automation rules. This
|
||||
makes rules easier to maintain and facilitates collaboration between users.
|
||||
- To modify the :doc:`model <models_modules_apps>` targeted by the automation rule, switch models
|
||||
before clicking :guilabel:`Automations` in Studio, or :ref:`activate developer mode
|
||||
<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.
|
||||
- Automation rules can be created from any kanban stage by clicking the :icon:`fa-cog`
|
||||
:guilabel:`(Settings)` icon that appears when hovering over 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 it can be changed if necessary.
|
||||
|
||||
.. image:: automated_actions/automations-kanban.png
|
||||
:alt: Create automations from a kanban stage
|
||||
@@ -41,102 +57,143 @@ To create an automation rule with Studio, proceed as follows:
|
||||
Trigger
|
||||
=======
|
||||
|
||||
The :guilabel:`Trigger` is used to define when the automation rule should be applied. The available
|
||||
triggers depend on the :doc:`model <models_modules_apps>`. Five trigger categories are available
|
||||
overall:
|
||||
The :guilabel:`Trigger` is used to define what kind of event needs to occur for the automation rule
|
||||
to run. The available triggers depend on the :doc:`model <models_modules_apps>`. Five trigger
|
||||
categories are available overall:
|
||||
|
||||
- :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`
|
||||
- :ref:`studio/automated-actions/trigger-values-updated`
|
||||
- :ref:`studio/automated-actions/trigger-email-events`
|
||||
- :ref:`studio/automated-actions/trigger-timing-conditions`
|
||||
- :ref:`studio/automated-actions/trigger-custom`
|
||||
- :ref:`studio/automated-actions/trigger-external`
|
||||
|
||||
.. _studio/automated-actions/conditions:
|
||||
|
||||
Adding conditions
|
||||
-----------------
|
||||
|
||||
Domain filters allow you to determine the records an automation rule should target or exclude.
|
||||
Efficient filtering enhances overall performance as it avoids unnecessary processing on records that
|
||||
are not impacted by the rule.
|
||||
|
||||
.. 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 <studio/automated-actions/trigger/values-timing-conditions>` and
|
||||
:ref:`Apply on <studio/automated-actions/trigger/custom>` filters are checked *during* the
|
||||
execution of the automation rule.
|
||||
:ref:`Activate developer mode <developer-mode>` before creating an automation rule to have the
|
||||
most flexibility in adding domain filters.
|
||||
|
||||
To define a :guilabel:`Before Update Domain`, :ref:`activate the developer mode
|
||||
<developer-mode>`, create or edit an automation rule, click :guilabel:`Edit Domain`, then click
|
||||
:guilabel:`New Rule`.
|
||||
Depending on the trigger chosen, it is possible to define one or more conditions a record must meet
|
||||
*before* and/or *after* a trigger occurs.
|
||||
|
||||
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`.
|
||||
- The :guilabel:`Before Update Domain` defines the conditions a record must meet *before* the
|
||||
trigger event occurs, e.g., the record must have `Type = Customer Invoice` and `Status = Posted`.
|
||||
|
||||
With :ref:`developer mode activated <developer-mode>`, click :guilabel:`Edit Domain`, if
|
||||
available, then :guilabel:`New Rule`.
|
||||
|
||||
- :guilabel:`Extra Conditions`, or in some cases :guilabel:`Apply on` filters, define the conditions
|
||||
a record must meet *after* the trigger event occurs, e.g., the customer invoice must have `Payment
|
||||
Status = Partially Paid`.
|
||||
|
||||
With :ref:`developer mode activated <developer-mode>` if needed, click :guilabel:`Add conditions`
|
||||
or :guilabel:`Edit Domain`, as relevant, then :guilabel:`New Rule`.
|
||||
|
||||
When a :ref:`trigger <studio/automated-actions/trigger>` occurs, e.g., the payment status of a
|
||||
posted customer invoice is updated, the automation rule checks the defined conditions and only
|
||||
executes the :ref:`action <studio/automated-actions/action>` if the record matches those conditions.
|
||||
|
||||
.. example::
|
||||
If the automated action should be executed when an email address is set for the first time (in
|
||||
contrast to modifying an email address) on an existing contact that is an individual rather than
|
||||
a company, use `Email is not set` and `Is a Company is not set` as the :guilabel:`Before Update
|
||||
Domain` and `Email is set` as the :guilabel:`Apply on` domain.
|
||||
|
||||
.. image:: automated_actions/before-update-domain.png
|
||||
:alt: Example of a trigger with a Before Update Domain
|
||||
:scale: 80%
|
||||
|
||||
.. _studio/automated-actions/trigger/values-updated:
|
||||
.. note::
|
||||
The :guilabel:`Before Update Domain` is not checked upon the creation of a record.
|
||||
|
||||
.. _studio/automated-actions/trigger-values-updated:
|
||||
|
||||
Values Updated
|
||||
--------------
|
||||
|
||||
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.
|
||||
Trigger automated actions when specific changes happen in the database. The triggers available in
|
||||
this category depend on the model and are based on common changes, such as adding a specific tag
|
||||
(e.g., to a task) or setting a field's value (e.g., setting the :guilabel:`User` field).
|
||||
|
||||
.. image:: automated_actions/values-updated-trigger.png
|
||||
:alt: Example of a Values Updated trigger
|
||||
Select the trigger, then select a value if required.
|
||||
|
||||
.. _studio/automated-actions/trigger/email-events:
|
||||
.. _studio/automated-actions/trigger-email-events:
|
||||
|
||||
Email Events
|
||||
------------
|
||||
|
||||
Trigger automated actions upon receiving or sending emails.
|
||||
|
||||
.. _studio/automated-actions/trigger/values-timing-conditions:
|
||||
.. _studio/automated-actions/trigger-timing-conditions:
|
||||
|
||||
Timing Conditions
|
||||
-----------------
|
||||
|
||||
Trigger automated actions based on a date field. The following triggers are available:
|
||||
Trigger automated actions at a point in time relative to a date field or to the creation or update
|
||||
of a record. 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.
|
||||
- :guilabel:`Based on date field`: The action is triggered a defined period of time before or after
|
||||
the date of the selected date field.
|
||||
- :guilabel:`After creation`: The action is triggered a defined period of time after a record is
|
||||
created and saved.
|
||||
- :guilabel:`After last update`: The action is triggered a defined period of time after 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.
|
||||
- a :guilabel:`Delay`: Specify the number of :guilabel:`Minutes`, :guilabel:`Hours`,
|
||||
:guilabel:`Days`, or :guilabel:`Months` after which the action should be triggered. If you
|
||||
selected the :guilabel:`Based on date field` trigger, the action can be triggered
|
||||
:guilabel:`After` or :guilabel:`Before` the selected date field.
|
||||
|
||||
.. note::
|
||||
By default, the scheduler checks for time-triggered automation rules every 240 minutes, or 4
|
||||
hours. This frequency is generally sufficient for delays such as 3 months after the order date
|
||||
or 7 days after the last update.
|
||||
|
||||
For delays of less than the equivalent of 2400 minutes, or 40 hours, the system recalculates
|
||||
the frequency of this check to ensure that more granular delays, e.g., 1 hour before the event
|
||||
start date and time, or 30 minutes after creation, can be respected as closely as possible.
|
||||
|
||||
To view or manually edit the frequency of the scheduler for a time-triggered automation rule,
|
||||
with :ref:`developer mode activated <developer-mode>`, click :guilabel:`Scheduled action`.
|
||||
|
||||
.. image:: automated_actions/trigger-delay-scheduled-action.png
|
||||
:alt: Direct link to scheduled action for automations
|
||||
|
||||
In the :guilabel:`Automation Rules: check and execute` scheduled action that opens, update the
|
||||
value of the :guilabel:`Execute Every` field, if desired. Clicking :guilabel:`Run Manually`
|
||||
triggers the scheduled action to run immediately. To return to the automation rule setup, click
|
||||
the automation rule name in the breadcrumbs.
|
||||
|
||||
- :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.
|
||||
met for the automation rule to run. Click :guilabel:`New Rule` to add another condition.
|
||||
|
||||
The action is triggered when the delay is reached and the conditions are met.
|
||||
The action is executed 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::
|
||||
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/custom:
|
||||
.. _studio/automated-actions/trigger-custom:
|
||||
|
||||
Custom
|
||||
------
|
||||
|
||||
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
|
||||
<studio/views/general/form>`, even before saving the record.
|
||||
- :guilabel:`On create`: when a record is saved for the first time.
|
||||
- :guilabel:`On create and edit`: when a record is saved for the first time and any subsequent time.
|
||||
- :guilabel:`On deletion`: when a record is deleted.
|
||||
- :guilabel:`On UI change`: when a field's value is changed on the :ref:`Form view
|
||||
<studio/views/general/form>`, even before the record is saved.
|
||||
|
||||
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.
|
||||
For the :guilabel:`On create and edit` 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
|
||||
@@ -146,137 +203,239 @@ Optionally, you can also define additional conditions to be met to trigger the a
|
||||
the :guilabel:`Apply on` field.
|
||||
|
||||
.. note::
|
||||
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.
|
||||
The :guilabel:`On UI change` trigger can only be used with the :ref:`Execute Code
|
||||
<studio/automated-actions/action-execute-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/external:
|
||||
.. _studio/automated-actions/trigger-external:
|
||||
|
||||
External
|
||||
--------
|
||||
|
||||
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.
|
||||
Trigger automated actions based on a specific event in an external system or application using a
|
||||
:doc:`webhook <automated_actions/webhooks>`.
|
||||
|
||||
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.
|
||||
After the webhook is configured in Odoo, where the webhook's URL is generated and the target record
|
||||
defined, it needs to be implemented in the external system.
|
||||
|
||||
.. 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.
|
||||
It is *highly recommended* to consult with a developer, solution architect, or another technical
|
||||
role when deciding to use webhooks and throughout the implementation process. If not properly
|
||||
configured, webhooks may disrupt the Odoo database and can take time to revert.
|
||||
|
||||
.. image:: automated_actions/webhook-update-record.png
|
||||
:alt: Example of a Based on date field trigger
|
||||
:scale: 80%
|
||||
|
||||
.. note::
|
||||
- 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).
|
||||
|
||||
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.
|
||||
It is also possible to set up an automated action that :ref:`sends data to a external system's
|
||||
webhook <studio/automated-actions/action-webhook>` when an event occurs in your Odoo database.
|
||||
|
||||
.. seealso::
|
||||
:doc:`automated_actions/webhooks`
|
||||
:doc:`Webhook documentation <automated_actions/webhooks>`
|
||||
|
||||
.. _studio/automated-actions/action:
|
||||
|
||||
Actions
|
||||
=======
|
||||
|
||||
Once you have defined the automation rule's :ref:`trigger <studio/automated-actions/trigger>`, click
|
||||
:guilabel:`Add an action` to define the action to be executed.
|
||||
Once you have defined the automation rule's :ref:`trigger <studio/automated-actions/trigger>`,
|
||||
click :guilabel:`Add an action` in the :guilabel:`Actions To Do` tab to define the action(s) to be
|
||||
executed.
|
||||
|
||||
.. 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.
|
||||
You can define multiple actions for the same automation rule. By default, actions are executed in
|
||||
the order in which they were defined.
|
||||
|
||||
.. _studio/automated-actions/action/update-record:
|
||||
This means, for example, that if you define an :guilabel:`Update record` action and then a
|
||||
:guilabel:`Send email` action where the email references the field that was updated, 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 record is updated.
|
||||
|
||||
To change the order of defined actions, click the :icon:`oi-draggable` :guilabel:`(drag handle)`
|
||||
icon beside an action and drag it to the desired position.
|
||||
|
||||
.. _studio/automated-actions/action-update-record:
|
||||
|
||||
Update Record
|
||||
-------------
|
||||
|
||||
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.
|
||||
This action is used to update one of the record's (related) fields. The following options are
|
||||
available:
|
||||
|
||||
If you selected a :ref:`many2many field <studio/fields/relational-fields-many2many>`, 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`.
|
||||
- :guilabel:`Update`: updates the selected field with the specified value.
|
||||
- :guilabel:`Update with AI`: updates the selected field dynamically based on the AI prompt
|
||||
provided. This option requires the **Odoo AI** app to be installed.
|
||||
- :guilabel:`Compute`: updates the selected field dynamically using Python code.
|
||||
|
||||
To define the action:
|
||||
|
||||
#. With the :guilabel:`Update`, :guilabel:`Update with AI`, or :guilabel:`Compute` option selected,
|
||||
as relevant, select or search for the field to be updated in the list that opens. If needed,
|
||||
click the :icon:`oi-chevron-right` :guilabel:`(right arrow)` next to the field name to access the
|
||||
list of related fields.
|
||||
#. Provide the relevant information based on the option selected.
|
||||
|
||||
Update
|
||||
~~~~~~
|
||||
|
||||
Select or enter the updated value for the field.
|
||||
|
||||
If a :ref:`many2many field <studio/fields/relational-fields-many2many>` is being updated, 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`.
|
||||
|
||||
.. 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.
|
||||
:guilabel:`Update` field to :guilabel:`Customer > Tags`, select :guilabel:`by Removing`, then
|
||||
select the tag to be removed.
|
||||
|
||||
.. image:: automated_actions/update-record-action.png
|
||||
.. image:: automated_actions/update-record-tags.png
|
||||
:alt: Example of an Update Record action
|
||||
:scale: 80%
|
||||
|
||||
.. 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 <studio/fields/simple-fields-date-time>` 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:
|
||||
Update with AI
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Enter a prompt to instruct Odoo AI how to update the field. Type `/` to open the :guilabel:`AI
|
||||
prompt tools`; use :guilabel:`Field Selector` to tell Odoo AI which related fields to check for
|
||||
context, and :guilabel:`Records Selector` to provide possible values for the updated field.
|
||||
|
||||
.. example::
|
||||
If you want the automation rule to update the :guilabel:`Assignees` field of a newly created
|
||||
task based on the employees' expertise, you can write a prompt to instruct the Odoo AI to check
|
||||
the :guilabel:`Display Name` field of the task for the context, then to assign the most suitable
|
||||
employee.
|
||||
|
||||
.. image:: automated_actions/update-record-ai.png
|
||||
:alt: Example of an Update Record action using AI
|
||||
:scale: 80%
|
||||
|
||||
Compute
|
||||
~~~~~~~
|
||||
|
||||
Enter the code to be used for computing the field's value.
|
||||
|
||||
.. example::
|
||||
If you want the automation rule to compute a custom :ref:`datetime field
|
||||
<studio/fields/simple-fields-date-time>`, :guilabel:`Escalated on`, when a task's priority is set
|
||||
to `Very high` (three stars), you can define the trigger :guilabel:`Priority is set to` to `Very
|
||||
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
|
||||
:scale: 80%
|
||||
|
||||
.. _studio/automated-actions/action-create-record:
|
||||
|
||||
Create Record and Duplicate Record
|
||||
----------------------------------
|
||||
|
||||
These actions are used to create a new or duplicated record on any model.
|
||||
|
||||
To define the action:
|
||||
|
||||
#. With :guilabel:`Create Record` or :guilabel:`Duplicate Record` selected as the :guilabel:`Type`
|
||||
of action, as relevant, select the required model in the :guilabel:`Record to Create` field; the
|
||||
field contains the current model by default.
|
||||
#. Specify a :guilabel:`Name` for the record, or, if the action duplicates a record, indicate the
|
||||
record being duplicated in the :guilabel:`Duplicate from` field.
|
||||
#. If the new or duplicated record is being created on another model, select a field in the
|
||||
:guilabel:`Link Field` field to link the record that triggered the creation of the new or
|
||||
duplicated record.
|
||||
|
||||
.. tip::
|
||||
The :guilabel:`Link Field` dropdown menu only contains :ref:`one2many fields
|
||||
<studio/fields/relational-fields-one2many>` existing on the current model that are linked to a
|
||||
:ref:`many2one field <studio/fields/relational-fields-many2one>` on the target model.
|
||||
|
||||
.. example::
|
||||
If you want the automation rule to duplicate a project, e.g. a project template with predefined
|
||||
tasks, when an opportunity is set to `Won`, add a custom `Related opportunity` :ref:`many2one
|
||||
field <studio/fields/relational-fields-many2one>` field on the *Project* model and a custom
|
||||
`Related project` :ref:`one2many field <studio/fields/relational-fields-one2many>` field on the
|
||||
*Lead* model, then provide the following details about the record being duplicated:
|
||||
|
||||
.. image:: automated_actions/duplicate-record.png
|
||||
:alt: Duplicate a record in a different model
|
||||
:scale: 80%
|
||||
|
||||
.. tip::
|
||||
You can create another automation rule with :ref:`studio/automated-actions/action-update-record`
|
||||
actions to update the fields of the new or duplicated 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-create-activity:
|
||||
|
||||
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`:
|
||||
This action is used to schedule a new activity linked to the record.
|
||||
|
||||
- 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.
|
||||
To define the action:
|
||||
|
||||
#. With :guilabel:`Create Activity` selected as the :guilabel:`Type` of action, select the
|
||||
appropriate :guilabel:`Activity Type` from the dropdown menu.
|
||||
#. Enter a :guilabel:`Title`.
|
||||
#. Indicate by when the activity should be completed by specifying a number of :guilabel:`Days`,
|
||||
:guilabel:`Weeks`, or :guilabel:`Months` in the :guilabel:`Due Date In` field.
|
||||
#. Select a :guilabel:`User type`:
|
||||
|
||||
- To always assign the activity to the same user, select :guilabel:`Specific User`, then add the
|
||||
user in the :guilabel:`Responsible` field.
|
||||
- To target a user linked to the record dynamically, select :guilabel:`Dynamic User (based on
|
||||
record)`. If needed, change the :guilabel:`User Field` by clicking on the placeholder field
|
||||
name then selecting or searching for the user field in the list that appears. Clicking the
|
||||
:icon:`oi-chevron-right` :guilabel:`(right arrow)` next to the field name allows you to access
|
||||
related fields if needed.
|
||||
#. Optionally, add a :guilabel:`Note` to provide more information about the activity.
|
||||
|
||||
.. 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)`.
|
||||
After a proposition is sent to a opportunity with a high expected revenue, you want to create an
|
||||
activity for the salesperson's team leader to call the potential client to increase the chances
|
||||
of closing the deal.
|
||||
|
||||
To do so, set the :guilabel:`Activity Type` to :guilabel:`Call` and the :guilabel:`User Type` to
|
||||
:guilabel:`Dynamic User (based on record)`. Click on the placeholder field and select
|
||||
:guilabel:`Sales Team`, then click the :icon:`oi-chevron-right` :guilabel:`(right arrow)` and
|
||||
select :guilabel:`Team Leader`.
|
||||
|
||||
.. image:: automated_actions/create-activity-action.png
|
||||
:alt: Example of a Create Activity action
|
||||
:scale: 80%
|
||||
|
||||
.. _studio/automated-actions/action-send-email-sms:
|
||||
|
||||
Send Email and Send SMS
|
||||
-----------------------
|
||||
|
||||
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:
|
||||
|
||||
- :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.
|
||||
To define the action:
|
||||
|
||||
.. _studio/automated-actions/action/send-whatsapp:
|
||||
#. With :guilabel:`Send Email` or :guilabel:`Send SMS` selected as the :guilabel:`Type` of action,
|
||||
as relevant, select or create an :guilabel:`Email Template` or :guilabel:`SMS Template`.
|
||||
#. In the :guilabel:`Send Email As` or :guilabel:`Send SMS As` field, choose how you want to send the
|
||||
email or text message.
|
||||
|
||||
For an email, select:
|
||||
|
||||
- :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.
|
||||
|
||||
For a text message, select:
|
||||
|
||||
- :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-send-whatsapp:
|
||||
|
||||
Send WhatsApp
|
||||
-------------
|
||||
@@ -286,41 +445,48 @@ Send WhatsApp
|
||||
:ref:`WhatsApp templates <productivity/whatsapp/templates>` must be created.
|
||||
|
||||
This action is used to send a WhatsApp message to a contact linked to a specific record.
|
||||
To do so, select the appropriate :guilabel:`WhatsApp Template` from the drop-down menu.
|
||||
|
||||
.. _studio/automated-actions/action/add-followers:
|
||||
With :guilabel:`Send WhatsApp` selected as the :guilabel:`Type` of action, select the appropriate
|
||||
:guilabel:`WhatsApp Template` from the dropdown menu.
|
||||
|
||||
.. _studio/automated-actions/action-add-remove-followers:
|
||||
|
||||
Add Followers and Remove Followers
|
||||
----------------------------------
|
||||
|
||||
Use these actions to (un)subscribe existing contacts to/from the record.
|
||||
This action is used to subscribe/unsubscribe existing contacts as followers of the record.
|
||||
|
||||
Create Record
|
||||
-------------
|
||||
With :guilabel:`Add Followers` or :guilabel:`Remove Followers` selected as the :guilabel:`Type` of
|
||||
action, as relevant, select a :guilabel:`Followers Type`:
|
||||
|
||||
This action is used to create a new record on any model.
|
||||
- To always add/remove the same contact(s), select :guilabel:`Specific Followers` then select the
|
||||
contact(s) from the dropdown menu. Multiple contacts can be added/removed.
|
||||
|
||||
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.
|
||||
- To add/remove a contact linked to the record dynamically, select :guilabel:`Dynamic Followers`. If
|
||||
needed, change the :guilabel:`Followers Field` by clicking on the placeholder field name then
|
||||
selecting or searching for the partner field in the list that appears. Clicking the
|
||||
:icon:`oi-chevron-right` :guilabel:`(right arrow)` next to the field name allows you to access
|
||||
related fields if needed.
|
||||
|
||||
.. note::
|
||||
The dropdown list related to the :guilabel:`Link Field` field only contains :ref:`one2many fields
|
||||
<studio/fields/relational-fields-one2many>` existing on the current model that are linked to a
|
||||
:ref:`many2one field <studio/fields/relational-fields-many2one>` on the target model.
|
||||
.. example::
|
||||
To keep customers informed of progress on a project, this automated action adds the relevant
|
||||
customer as a follower when a project task is set to `In progress`.
|
||||
|
||||
.. tip::
|
||||
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.
|
||||
.. image:: automated_actions/add-followers-action.png
|
||||
:alt: Adding the customer as a follower when project task set to in progress
|
||||
:scale: 80%
|
||||
|
||||
.. _studio/automated-actions/action/python-code:
|
||||
.. _studio/automated-actions/action-execute-code:
|
||||
|
||||
Execute Code
|
||||
------------
|
||||
|
||||
.. important::
|
||||
For automation rules that require the execution of :ref:`custom code
|
||||
<studio/automated-actions/action-execute-code>`, note that maintenance of custom code is not
|
||||
included in the *Standard* or *Custom* pricing plans and incurs :ref:`additional fees
|
||||
<charges_standard>`.
|
||||
|
||||
This action is used to execute Python code. You can write your code into the :guilabel:`Code` tab
|
||||
using the following variables:
|
||||
|
||||
@@ -341,25 +507,44 @@ using the following variables:
|
||||
.. tip::
|
||||
The available variables are described both in the :guilabel:`Code` and :guilabel:`Help` tabs.
|
||||
|
||||
.. seealso::
|
||||
:doc:`Odoo's ORM capabilities <../../developer/reference/backend/orm>`
|
||||
|
||||
.. _studio/automated-actions/action-webhook:
|
||||
|
||||
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.
|
||||
This action is used to send a `POST` API request with the values of the selected :guilabel:`Fields`
|
||||
to the webhook 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:
|
||||
.. note::
|
||||
It is also possible to set up an automated action that :doc:`uses a webhook to receive data from
|
||||
an external system <automated_actions/webhooks>` when a predefined event occurs in that system.
|
||||
|
||||
Execute Existing Actions
|
||||
------------------------
|
||||
.. _studio/automated-actions/action-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.
|
||||
Multi Actions
|
||||
-------------
|
||||
|
||||
This action is used to trigger multiple actions (linked to the current model) at the same time.
|
||||
|
||||
To define the actions:
|
||||
|
||||
#. With :guilabel:`Multi Actions` selected as the :guilabel:`Type` of action, click :guilabel:`Add
|
||||
an action`.
|
||||
#. In the :guilabel:`Add: Child Actions` pop-up:
|
||||
|
||||
- select one or more existing actions and click :guilabel:`Select`; or
|
||||
- click :guilabel:`New`, define the action to be executed, then click :guilabel:`Save & Close`
|
||||
or, to create additional actions, :guilabel:`Save & New` .
|
||||
#. Repeat as many times as needed.
|
||||
|
||||
.. image:: automated_actions/multi-actions.png
|
||||
:alt: Define multiple actions to be executed
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 14 KiB |
BIN
content/applications/studio/automated_actions/multi-actions.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 31 KiB |
@@ -7,280 +7,278 @@ Webhooks
|
||||
role when deciding to use webhooks and throughout the implementation process. If not properly
|
||||
configured, webhooks may disrupt the Odoo database and can take time to revert.
|
||||
|
||||
Webhooks, which can be created in **Studio**, are automation rules triggered by external events via
|
||||
user-defined HTTP callbacks. When an external system sends data to an Odoo webhook's URL (the
|
||||
"trigger") with a data file (the "payload"), Odoo responds with a predefined action in the database.
|
||||
Webhooks, which can be created in **Odoo Studio**, allow you to automate an action in your Odoo
|
||||
database when a specific event occurs in another, external system.
|
||||
|
||||
Unlike scheduled actions or manual API calls, webhooks enable real-time communication and
|
||||
automation. For example, if a sales order is confirmed in an external POS system, a webhook can
|
||||
instantly update Odoo's inventory, ensuring system synchronization.
|
||||
In practice, this works as follows: when the event occurs in the external system, a data file (the
|
||||
"payload") is sent to the Odoo webhook's URL via a `POST` API request, and a predefined action is
|
||||
performed in your Odoo database.
|
||||
|
||||
Unlike scheduled actions, which run at predefined intervals, or manual API requests, which need to
|
||||
be explicitly invoked, webhooks enable real-time, event-driven communication and automation. For
|
||||
example, you can set up a webhook to have your Odoo inventory data updated automatically when a
|
||||
sales order is confirmed in an external point-of-sale system.
|
||||
|
||||
Setting up a webhook in Odoo requires no coding when connecting two Odoo databases, but
|
||||
:ref:`testing a webhook <studio/webhooks/test-webhook>` requires an external tool.
|
||||
:ref:`Custom target records or actions <studio/webhooks/webhook-example>` may require programming
|
||||
skills.
|
||||
|
||||
.. note::
|
||||
This article covers creating a webhook that *takes in* data from an external source. However,
|
||||
an automated action that :ref:`sends an API call to an external webhook
|
||||
<studio/automated-actions/action-webhook>` can also be created.
|
||||
This article covers creating a webhook that *receives* data from an external source. However,
|
||||
it is also possible to create an automated action that :ref:`sends data to an external webhook
|
||||
<studio/automated-actions/action-webhook>` when a change occurs in your Odoo database.
|
||||
|
||||
Create a webhook in Studio
|
||||
==========================
|
||||
.. _studio/webhooks/create-webhook:
|
||||
|
||||
Webhooks are configured in **Studio**, and their setup is split between their :ref:`trigger
|
||||
<studio/webhooks/webhook_trigger>` and their :ref:`actions <studio/webhooks/webhook_action>`.
|
||||
Create a webhook in Odoo
|
||||
========================
|
||||
|
||||
.. important::
|
||||
Before implementing a webhook in a live database, configure and test it using a :ref:`duplicate
|
||||
database <odoo_online/database-management>` to ensure the webhook performs as intended.
|
||||
|
||||
.. tip::
|
||||
- Setting up a webhook in Odoo requires no coding when connecting Odoo databases, but testing
|
||||
requires an external tool like `Postman <https://www.postman.com/>`_. :ref:`Custom target
|
||||
records or actions <studio/webhooks/webhook-example>` may require programming skills.
|
||||
- :ref:`Activate developer mode <developer-mode>` to modify the model targeted by the webhook
|
||||
(e.g., sales orders or contact information) and to find the model's technical name (which may be
|
||||
required for proper payload configuration).
|
||||
:ref:`Activating developer mode <developer-mode>` before creating up a webhook gives greater
|
||||
flexibility in selecting the :doc:`model <../models_modules_apps>` the automation rule
|
||||
targets. It also allows you to find the technical name of the model and fields, which may be
|
||||
needed to configure the payload.
|
||||
|
||||
.. _studio/webhooks/webhook_trigger:
|
||||
To find a model's technical name, with developer mode activated, hover over the model name and
|
||||
then click :icon:`fa-arrow-right` :guilabel:`(Internal link)`. The technical name can be found in
|
||||
the :guilabel:`Model` field. For example, a sales order webhook uses the *Sales
|
||||
Order* model, but the technical name `sale.order` is used in the payload.
|
||||
|
||||
Set the webhook's trigger
|
||||
-------------------------
|
||||
To create a webhook in **Studio**, proceed as follows:
|
||||
|
||||
To create a webhook with **Studio**, :ref:`open Studio <studio/access>`, click :guilabel:`Webhooks`,
|
||||
then :guilabel:`New`. From here, name the webhook, modify the webhook's model (the kind of database
|
||||
entry to be targeted) if needed, and toggle whether calls made to the webhook URL should be logged
|
||||
(which would track the webhook's call history for troubleshooting).
|
||||
#. :ref:`Open Studio <studio/access>` and click :guilabel:`Webhooks`, then :guilabel:`New`.
|
||||
#. Give the webhook a clear, meaningful name that identifies its purpose.
|
||||
#. If needed, and provided developer mode is activated, select the appropriate :guilabel:`Model`
|
||||
from the dropdown. If developer mode is not activated, the automation rule targets the current
|
||||
model by default.
|
||||
|
||||
The webhook's URL is automatically generated. This is the URL that should be used for testing the
|
||||
webhook and connecting it to the external system that will send updates to the database.
|
||||
#. The webhook's URL is automatically generated, but can be changed if needed by clicking
|
||||
:guilabel:`Rotate Secret`. This is the URL that should be used when implementing the webhook in
|
||||
the external system that will send updates to the database.
|
||||
|
||||
.. danger::
|
||||
The webhook's URL is **confidential** and should be treated with care. Sharing it online or
|
||||
without caution can provide unintended access to the Odoo database. Click :guilabel:`Rotate
|
||||
Secret` to change the URL if needed.
|
||||
.. warning::
|
||||
The URL is **confidential** and should be treated with care. Sharing it online or without
|
||||
caution can provide unintended access to the Odoo database. If the URL is updated after the
|
||||
initial implementation, make sure to update it in the external system.
|
||||
|
||||
Finally, if the system sending the webhook is not Odoo, adjust the :guilabel:`Target Record` actions
|
||||
to look for the JSON record that is included in the API call's payload when the call is made to the
|
||||
webhook's URL. If the system sending the webhook is an Odoo database, then make sure that the `id`
|
||||
and `model` appear in the payload.
|
||||
#. If desired, enable :guilabel:`Log Calls` to track the history of API requests made to the
|
||||
webhook's URL, e.g., for troubleshooting purposes.
|
||||
|
||||
#. If the system sending the webhook is not Odoo, adjust the :guilabel:`Target Record` code to look
|
||||
for the JSON record included in the payload when the API request is made to the webhook's URL. If
|
||||
the system sending the webhook is an Odoo database, ensure that the `id` and `model` appear in
|
||||
the payload.
|
||||
|
||||
If the webhook is used to create records in the Odoo database, use `model.browse(i)` or
|
||||
`model.search(i)` instead of the default :guilabel:`Target Record` format.
|
||||
|
||||
#. Click :guilabel:`Add an action` in the :guilabel:`Actions To Do` tab to define the :ref:`actions
|
||||
<studio/automated-actions/action>` to be executed.
|
||||
#. Before implementing the webhook in the external system, :ref:`test
|
||||
<studio/webhooks/test-webhook>` it to ensure it works as intended.
|
||||
|
||||
.. tip::
|
||||
Although the :guilabel:`Model` is set in Odoo, it is the model's technical name that must be
|
||||
included in the payload. Hover over the model name, then click the :icon:`fa-arrow-right`
|
||||
:guilabel:`(Internal link)` icon to find this technical name in the :guilabel:`Model` field. For
|
||||
example, a sales order webhook uses the *Sales Order* model, but the technical name `sale.order`
|
||||
is used in the payload.
|
||||
- Webhooks can also be created via the :guilabel:`Automations` menu in **Studio** by selecting
|
||||
the trigger :guilabel:`On webhook`.
|
||||
- To access the history of API requests if :guilabel:`Log Calls` has been enabled, click the
|
||||
:guilabel:`Logs` smart button at the top of the :guilabel:`Automation rules` form.
|
||||
- If the purpose of the webhook is anything other than to update an existing record, e.g., to
|
||||
create a new record, the :guilabel:`Execute Code` action must be chosen.
|
||||
|
||||
.. note::
|
||||
When creating a record in the Odoo database, the target record's default format should not be
|
||||
used. Instead, use `model.browse(i)` or `model.search(i)`.
|
||||
.. _studio/webhooks/test-webhook:
|
||||
|
||||
.. _studio/webhooks/webhook_action:
|
||||
Test a webhook
|
||||
==============
|
||||
|
||||
Set the webhook's action
|
||||
------------------------
|
||||
Testing a webhook requires a test payload and an external tool or system, like
|
||||
`Postman <https://www.postman.com/>`_, to send the payload via a `POST` API request. This section
|
||||
presents the steps to test a webhook in Postman.
|
||||
|
||||
To set a webhook's action while configuring a webhook, click :guilabel:`Add an action` under the
|
||||
:guilabel:`Actions To Do` tab. Click the action's :guilabel:`Type` and set the fields as needed.
|
||||
.. tip::
|
||||
- See the :ref:`webhook use cases section <studio/webhooks/webhook-examples>` for step-by-step
|
||||
explanations of how to test webhooks using test payloads.
|
||||
- To get specific help with testing a webhook with Postman, contact their support team.
|
||||
|
||||
.. _studio/webhooks/test_webhook:
|
||||
#. In Postman, create a new HTTP request and set its method to :guilabel:`POST`.
|
||||
#. Copy the webhook's URL from your Odoo database using the :icon:`fa-link` :guilabel:`(link)` icon
|
||||
and paste it into the URL field in Postman.
|
||||
#. Click the :guilabel:`Body` tab and select :guilabel:`raw`.
|
||||
#. Set the file type to :guilabel:`JSON`, then copy the code from the test payload and paste it into
|
||||
the code editor.
|
||||
#. Click :guilabel:`Send`.
|
||||
|
||||
Test the webhook
|
||||
----------------
|
||||
.. _studio/webhooks/test-webhook-response:
|
||||
|
||||
.. note::
|
||||
Testing the webhook requires the webhook to be set up, a test payload to send to the webhook, and
|
||||
an external tool or system to send the payload through a `POST` API request. Consider using a
|
||||
tool like `Postman <https://www.postman.com/>`_ so less technical skills are required.
|
||||
In the :guilabel:`Response` viewer at the bottom of the screen in Postman, details, including a HTTP
|
||||
response code, indicate whether or not the webhook is functioning correctly.
|
||||
|
||||
If a message saying `200 OK` or `status: ok` gets returned during testing, then the webhook is
|
||||
functioning properly on Odoo's side. From here, implementation can begin with the other tool to
|
||||
automatically send those webhook calls into Odoo using the webhook's URL.
|
||||
- A `200 OK` or `status: ok` message indicates that the webhook is functioning properly on Odoo's
|
||||
side. From here, implementation can begin with the other system to automatically send the API
|
||||
requests to the Odoo webhook's URL.
|
||||
|
||||
If any other responses are returned, the number sent in the response helps to identify the problem.
|
||||
For example, a `500 Internal Server Error` means that Odoo could not interpret the call properly. If
|
||||
this gets returned, ensure the fields found in the JSON file are properly mapped in the webhook's
|
||||
configuration and in the system sending the test call. Turning on call logging in the webhook's
|
||||
configuration provides error logs if the webhook is not functioning as intended.
|
||||
- If any other response is returned, the number associated with it helps to identify the problem.
|
||||
For example, a `500 Internal Server Error` message means that Odoo could not interpret the call
|
||||
properly. In this case, ensure the fields found in the JSON file are properly mapped in the
|
||||
webhook's configuration and in the system sending the test call.
|
||||
|
||||
Implement the webhook
|
||||
---------------------
|
||||
.. tip::
|
||||
Turning on call logging in the webhook's configuration in Odoo provides error logs if the webhook
|
||||
is not functioning as intended.
|
||||
|
||||
Once the webhook is fully configured, begin connecting it to the system that sends data to the Odoo
|
||||
database through this webhook. Make sure that the API calls are sent to the webhook's URL when
|
||||
setting that system up.
|
||||
Implement a webhook in an external system
|
||||
=========================================
|
||||
|
||||
.. _studio/webhooks/webhook_examples:
|
||||
When the webhook has been successfully created in Odoo and tested, implement it in the system that
|
||||
sends data to the Odoo database, making sure the `POST` API requests are sent to the webhook's URL.
|
||||
|
||||
.. _studio/webhooks/webhook-examples:
|
||||
|
||||
Webhook use cases
|
||||
=================
|
||||
|
||||
Below are two examples of how to use webhooks in Odoo. These webhooks require external tools (which
|
||||
are listed with the example).
|
||||
|
||||
.. warning::
|
||||
Consult with a developer, solution architect, or another technical role when deciding to
|
||||
implement webhooks. If not properly configured, webhooks may disrupt the Odoo database and can
|
||||
take time to revert.
|
||||
Below are two examples of how to use webhooks in Odoo. A test payload is provided for each example,
|
||||
and can be found in the section on testing the webhook. `Postman <https://www.postman.com/>`_ is
|
||||
used to send the test payload.
|
||||
|
||||
Update a sales order's currency
|
||||
-------------------------------
|
||||
|
||||
This webhook updates a sales order in the **Sales** app to USD. It useful for subsidiaries outside
|
||||
the United States with a mother company located inside the United States or during mergers when
|
||||
consolidating data into one Odoo database.
|
||||
This webhook updates a sales order in the **Sales** app to `USD` when the external system sends a
|
||||
`POST` API request to the webhook's URL that includes that sales order number (which is identified
|
||||
by the payload's `id` record).
|
||||
|
||||
Set the webhook's trigger
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
This could be useful for subsidiaries outside the United States with a mother company located inside
|
||||
the United States or during mergers when consolidating data into one Odoo database.
|
||||
|
||||
To set up this webhook, open the **Sales** app. Then, :ref:`set the trigger
|
||||
<studio/webhooks/webhook_trigger>` so the :guilabel:`Model` is set to `Sales Order`. Also, set
|
||||
the :guilabel:`Target Record` to `model.env[payload.get('model')].browse(int(payload.get('id')))`.
|
||||
This is broken down below.
|
||||
Create the webhook
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- **model**: what gets updated in Odoo (in this case, sales orders). This matches the
|
||||
:guilabel:`Model` set earlier.
|
||||
- **env**: where the action takes place. In this case, it is Odoo.
|
||||
- **payload**: what is sent to the webhook's URL. This contains the information that updates
|
||||
the sales order.
|
||||
- **get('model')**: tells the webhook what database record to look at. In this case, the
|
||||
webhook retrieves (`get`) the data tied to a specific `model`. In this example, this is the
|
||||
Sales Order model.
|
||||
- **browse**: tells the webhook to look in the `model` (Sales Order) set by the payload for what to
|
||||
update.
|
||||
- **int**: turns the target into an `integer` (a whole number). This is important in case some
|
||||
words (a `string`) or a decimal number is included in the payload's target record.
|
||||
- **get('id')**: identifies the sales order number that is being updated in Odoo.
|
||||
To create this webhook, proceed as follows:
|
||||
|
||||
Set the webhook's action
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#. Open the **Sales** app, then :ref:`open Studio <studio/access>` and click :guilabel:`Webhooks`.
|
||||
The *Sales Order* model is selected by default.
|
||||
#. Click :guilabel:`New`. The :guilabel:`Trigger` is set to :guilabel:`On webhook` by default.
|
||||
#. Set the :guilabel:`Target Record` to
|
||||
`model.env[payload.get('model')].browse(int(payload.get('id')))`, where:
|
||||
|
||||
After setting the trigger, set the webhook's action by clicking :guilabel:`Add an action`. For the
|
||||
:guilabel:`Type`, click :guilabel:`Update Record`. Then, select `Update`, choose the field
|
||||
`Currency`, and select `USD` to have the currency field updated to USD. Finally, click
|
||||
:guilabel:`Save & Close`.
|
||||
- `payload.get('model')` retrieves the value associated with the `model` key in the payload,
|
||||
i.e., `sale.order`, which is the technical name of the *Sales Order* model.
|
||||
- `payload.get('id')` retrieves the value associated with the `id` key in the payload, i.e.,
|
||||
the number of the target sales order in your Odoo database with the `S` and leading
|
||||
zeros removed.
|
||||
- `int` converts the retrieved id to an integer (i.e., a whole number) because the method
|
||||
`browse()` can only be used with an integer.
|
||||
|
||||
Webhook setup summary
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To summarize what is set up, the webhook targets sales orders, identified by their sales order
|
||||
number, and updates their currency to `USD` when a POST request is sent to the webhook's URL that
|
||||
includes that sales order number (which is identified by the payload's `id` record).
|
||||
#. Click :guilabel:`Add an action`.
|
||||
#. In the :guilabel:`Type` section, click :guilabel:`Update Record`.
|
||||
#. In the :guilabel:`Action details` section, select :guilabel:`Update`, choose the field
|
||||
:guilabel:`Currency`, and select :guilabel:`USD`.
|
||||
#. Click :guilabel:`Save & Close`.
|
||||
|
||||
Test the webhook
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Test the webhook's setup to make sure everything is correct. This process uses a tool called
|
||||
`Postman <https://www.postman.com/>`_ to send the simulated trigger.
|
||||
To test this webhook, proceed as follows:
|
||||
|
||||
This section walks through the steps to test this webhook in Postman, but does not offer help if
|
||||
there's an issue within that tool. To get specific help with Postman, contact their support team.
|
||||
#. With `Postman <https://www.postman.com/>`_ open, create a new HTTP request and set its method to
|
||||
:guilabel:`POST`.
|
||||
#. Copy the URL of the Odoo webhook using the :icon:`fa-link` :guilabel:`(link)` icon and paste it
|
||||
into the URL field in Postman.
|
||||
#. Click the :guilabel:`Body` tab and select :guilabel:`raw`.
|
||||
#. Set the file type to :guilabel:`JSON`, then copy this code, i.e., the payload, and paste it into
|
||||
the code editor:
|
||||
|
||||
Once Postman is open, create a new :guilabel:`HTTP` request and set its method to :guilabel:`POST`.
|
||||
Next, copy the webhook's URL that is being tested and paste it into the URL field in Postman. After
|
||||
that, click the :guilabel:`Body` tab and select the :guilabel:`raw` option. Set the file type to
|
||||
:guilabel:`JSON`, then copy this code and paste it into the file.
|
||||
.. code-block:: json
|
||||
|
||||
.. code-block:: json
|
||||
{
|
||||
"model": "sale.order",
|
||||
"id": "SALES ORDER NUMBER"
|
||||
}
|
||||
|
||||
{
|
||||
"model": "sale.order",
|
||||
"id": "SALES ORDER NUMBER"
|
||||
}
|
||||
|
||||
From here, choose a sales order to test the webhook on. If it is not possible to test in a live
|
||||
Odoo database, consider creating a demo database with a sample sales order and the webhook that was
|
||||
configured. Replace `SALES ORDER NUMBER` with the sales order's number without the `S` or any zeros
|
||||
before the number. For example, a sales order with the number `S00007` should be entered as `7` in
|
||||
Postman. Finally, click :guilabel:`Send` in Postman.
|
||||
|
||||
If a message saying `200 OK` or `status: ok` gets returned, then the webhook is functioning properly
|
||||
on Odoo's side. The test sales order's currency is updated. From here, implementation can begin with
|
||||
the other tool to automatically send those webhook calls into Odoo using the webhook's URL.
|
||||
|
||||
If any other responses are returned, the number associated with them helps to identify the problem.
|
||||
For example, a `500 Internal Server Error` means that Odoo could not interpret the call properly. If
|
||||
this gets returned, ensure the `model` and `id` fields are properly mapped in the webhook's
|
||||
configuration and in Postman.
|
||||
#. In your Odoo database, choose a sales order to test the webhook on. In the pasted code, replace
|
||||
`SALES ORDER NUMBER` with the sales order's number without the `S` or any zeros before the
|
||||
number. For example, a sales order with the number `S00007` should be entered as `7` in Postman.
|
||||
#. Click :guilabel:`Send`.
|
||||
#. Consult the :ref:`Response viewer <studio/webhooks/test-webhook-response>` in Postman to
|
||||
determine whether or not the webhook is functioning properly. If a message other than `200 OK` or
|
||||
`status: ok` is returned, the number associated with the message helps to identify the problem.
|
||||
|
||||
.. _studio/webhooks/webhook-example:
|
||||
|
||||
Create a new contact
|
||||
--------------------
|
||||
|
||||
This webhook uses custom code to create a new contact in an Odoo database. This could be helpful for
|
||||
automatically creating new vendors or customers.
|
||||
This webhook uses custom code to create a new contact in an Odoo database when the external system
|
||||
sends a `POST` API request to the webhook's URL that includes the contact's information. This could
|
||||
be helpful for automatically creating new vendors or customers.
|
||||
|
||||
Set the webhook's trigger
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Create the webhook
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To set up this webhook, open the **Contacts** app. Then, :ref:`set the trigger
|
||||
<studio/webhooks/webhook_trigger>` so the :guilabel:`Model` is set to `Contact`. Also, set the
|
||||
:guilabel:`Target Record` to `model.browse([2])`. This is broken down below.
|
||||
To create this webhook, proceed as follows:
|
||||
|
||||
- **model**: what gets updated in Odoo (in this case, a contact). This matches the :guilabel:`Model`
|
||||
set earlier.
|
||||
- **browse**: tells the webhook to look in the `model` (the contacts) set by the payload for
|
||||
what to create.
|
||||
#. Open the **Contacts** app, then :ref:`open Studio <studio/access>` and click :guilabel:`Webhooks`.
|
||||
The *Contact* model is selected by default.
|
||||
#. Click :guilabel:`New`. The :guilabel:`Trigger` is set to :guilabel:`On webhook` by default.
|
||||
#. Set the :guilabel:`Target Record` to `model.browse([2])`. This is essentially a placeholder as
|
||||
the code in the automated action tells the webhook what needs to be retrieved from the payload
|
||||
and in which model the record needs to be created.
|
||||
#. Click :guilabel:`Add an action`.
|
||||
#. In the :guilabel:`Type` section, click :guilabel:`Execute Code`.
|
||||
#. Copy this code and paste it into the code editor in the :guilabel:`Code` tab of the
|
||||
:guilabel:`Action details` section:
|
||||
|
||||
Set the webhook's action
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
.. code-block:: python
|
||||
|
||||
After setting the trigger, set the webhook's action by clicking :guilabel:`Add an action`. For the
|
||||
:guilabel:`Type`, click :guilabel:`Execute Code`, then set the :guilabel:`code` to the sample code
|
||||
below. Finally, click :guilabel:`Save & Close`.
|
||||
# variables to retrieve and hold data from the payload
|
||||
contact_name = payload.get('name')
|
||||
contact_email = payload.get('email')
|
||||
contact_phone = payload.get('phone')
|
||||
|
||||
.. code-block:: python
|
||||
# a Python function to turn the variables into a contact in Odoo
|
||||
if contact_name and contact_email:
|
||||
new_partner = env['res.partner'].create({
|
||||
'name': contact_name,
|
||||
'email': contact_email,
|
||||
'phone': contact_phone,
|
||||
'company_type':'person',
|
||||
'customer_rank': 1,
|
||||
})
|
||||
# an error message for missing required data in the payload
|
||||
else:
|
||||
raise ValueError("Missing required fields: 'name' and 'email'")
|
||||
|
||||
# variables to retrieve and hold data from the payload
|
||||
contact_name = payload.get('name')
|
||||
contact_email = payload.get('email')
|
||||
contact_phone = payload.get('phone')
|
||||
|
||||
# a Python function to turn the variables into a contact in Odoo
|
||||
if contact_name and contact_email:
|
||||
new_partner = env['res.partner'].create({
|
||||
'name': contact_name,
|
||||
'email': contact_email,
|
||||
'phone': contact_phone,
|
||||
'company_type':'person',
|
||||
'customer_rank': 1,
|
||||
})
|
||||
# an error message for missing required data in the payload
|
||||
else:
|
||||
raise ValueError("Missing required fields: 'name' and 'email'")
|
||||
|
||||
|
||||
Webhook setup summary
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To summarize what is set up, the webhook creates a contact when an API call is sent to the webhook's
|
||||
URL that includes the contact's information.
|
||||
#. Click :guilabel:`Save & Close`.
|
||||
|
||||
Test the webhook
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Test the webhook's setup to make sure everything is correct. This process uses a tool called
|
||||
`Postman <https://www.postman.com/>`_ to send the simulated trigger.
|
||||
To test this webhook, proceed as follows:
|
||||
|
||||
This section walks through the steps to test this webhook in Postman, but does not offer help if
|
||||
there's an issue within that tool. To get specific help with Postman, contact their support team.
|
||||
#. In `Postman <https://www.postman.com/>`_, create a new HTTP request and set its method to
|
||||
:guilabel:`POST`.
|
||||
#. Copy the URL of the Odoo webhook using the :icon:`fa-link` :guilabel:`(link)` icon and paste it
|
||||
into the URL field in Postman.
|
||||
#. Click the :guilabel:`Body` tab and select :guilabel:`raw`.
|
||||
#. Set the file type to :guilabel:`JSON`, then copy this code, i.e., the payload, and paste it into
|
||||
the code editor:
|
||||
|
||||
Once Postman is open, create a new request, and set its method to :guilabel:`POST`. Next, copy the
|
||||
webhook's URL that is being tested and paste it into the URL field in Postman. After that, click the
|
||||
:guilabel:`Body` tab and click :guilabel:`raw`. Set the file type to :guilabel:`JSON`, then copy
|
||||
this code and paste it into the file.
|
||||
.. code-block:: json
|
||||
|
||||
.. code-block:: json
|
||||
{
|
||||
"name": "CONTACT NAME",
|
||||
"email": "CONTACTEMAIL@EMAIL.COM",
|
||||
"phone": "CONTACT PHONE NUMBER"
|
||||
}
|
||||
|
||||
{
|
||||
"name": "CONTACT NAME",
|
||||
"email": "CONTACTEMAIL@EMAIL.COM",
|
||||
"phone": "CONTACT PHONE NUMBER"
|
||||
}
|
||||
|
||||
Replace the fields above with a new contact's information in Postman, and then click
|
||||
:guilabel:`Send`.
|
||||
|
||||
If a message saying `200 OK` or `status: ok` gets returned, then the webhook is functioning properly
|
||||
on Odoo's side. The new test contact appears in the **Contacts** app. From here, implementation can
|
||||
begin with the other tool to automatically send those webhook calls into Odoo using the webhook's
|
||||
URL.
|
||||
|
||||
If any other responses are returned, the number associated with them helps to identify the problem.
|
||||
For example, a `500 Internal Server Error` means that Odoo could not interpret the call properly. If
|
||||
this gets returned, ensure the fields found in the JSON file are properly mapped in the webhook's
|
||||
configuration and in Postman.
|
||||
#. In the pasted code, replace the `CONTACT NAME`, `CONTACTEMAIL@EMAIL.COM`, and `CONTACT PHONE
|
||||
NUMBER` with a new contact's information.
|
||||
#. Click :guilabel:`Send`.
|
||||
#. Consult the :ref:`Response viewer <studio/webhooks/test-webhook-response>` in Postman to
|
||||
determine whether or not the webhook is functioning properly. If a message other than `200 OK` or
|
||||
`status: ok` is returned, the number associated with the message helps to identify the problem.
|
||||
|
||||