Index
Webhooks allow other systems to notify Slingshot to perform some action.
Currently, we support Flow Production Tracking Webhooks.
This allows Flow to notify Slingshot when specific events occur, so Slingshot can perform actions of its own.
For example, when a user changes a Version status in Flow, a webhook could notify Slingshot and Slingshot could then update the Task and Shot statuses to match.
Configuration¶
webhooks:
update_entity: # (1)!
triggers:
Version/update/sg_status_list: # (2)!
- description: set task to final/pending when version status is set # (9)!
trigger_values: [fnl, pnd] # (3)!
update_entity: SELF # (4)!
update_filters: null # (5)!
update_data: # (6)!
sg_task.Task.sg_status_list: $new_value
multi_entity_update_modes: # (8)!
sg_multientities: set
- description: set shot to final when version is finalled
trigger_values: # (7)!
- fnl
update_entity: SELF
update_filters: null
update_data:
entity.Shot.sg_status_list: fnl
- Currently the only valid webhook type is
update_entity
. - See trigger entities
- The webhook will only trigger if the field has changed to one of these values.
IfNone
, the webhook will always trigger. - The Entity type to update. If
SELF
, it will update the same entity that triggered the webhook. - If
update_entity
is notSELF
, these filters are used to select which specific entities of typeupdate_entity
will be updated. For filter syntax, see: Shotgrid rest-api - The new values to set on the filtered entities. See update_data
- Each trigger can have as many action blocks as needed to peform different actions for different
trigger_values
or to update different entities. -
Optional. How to treat updates to multi-entity fields.
Can be
set
,add
, orremove
. The default isset
. -
Descriptions are optional and currently only used for our internal reference.
Triggers¶
Trigger definitions are in the format: Entity/event[/field].
Valid events are create
, update
, delete
, and revive
.1
For Example:
- Version/update/sg_status_list: triggers when a
Version
sg_status_list
field ischanged
. - Shot/create: triggers when a
Shot
iscreated
update_data¶
Update data is a dictionary of update entity field: value
pairs.
Variables¶
$trigger_entity
: the triggering entity dictionary, e.g.{"id": 1, "type": "Version"}
$trigger_entity.id
: the tiggering entity ID, e.g.1234
$trigger_entity.type
: the triggering entity type, e.g.Version
$tigger_entity.\*
: the value of any valid field on the triggering entity$new_value
: when event isupdate
, the value the field was changed _to$old_value
: when event isupdate
, the value the field was changed _from$project
: the project the entity belongs to, e.g.{"id": 1, "type": "Project"}
$user
: the user who made the change, e.g.{"id": 1, "type": "HumanUser"}
$changed_field
: the name of the field that changed, e.g.sg_status_list
Template Examples¶
update_data:
# sets sg_description to "Hello!"
sg_description: Hello!
# sets sg_status_list (Status) to rev (Pending Review)
sg_status_list: rev
# sets the Task status to the value the triggering entity field was just changed to
sg_task.Task.sg_status_list: $new_value
# sets the linked Shot status to Final
entity.Shot.sg_status_list: fnl
Installation in Flow Production Tracking2¶
- In the Flow project, go to the Admin menu and select "Webooks"
- Click on "+Create Webook"
- Add a Name
- Add URL:
(where the Xs are replaced with the show's ID)
- Get "Secret Token" from Geoff (for now)
- Make sure "Validate SSL Certificate" and "Deliver in Batched Format" are both checked
- Under "Notify when unstable" select 'Slingshot Systems'
- Select the appropriate "Project"
- "Entity Type" is usually Shot, Version, Asset, etc.
- You can add as many triggering "Fields" as necessary
- Click "Save"
Common Examples¶
Update Shot and Task Statuses when a Version is Finalled¶
webhooks:
update_entity:
triggers:
Version/update/sg_status_list: # (1)!
- description: set task to final when version is final
trigger_values: # (2)!
- fnl # (3)!
update_entity: Task # (4)!
update_filters: # (5)!
- - sg_versions
- is
- $trigger_entity
update_data:
sg_status_list: fnl # (6)!
- description: set shot to final when version is final
trigger_values: # (7)!
- fnl
update_entity: SELF # (8)!
update_filters: null # (9)!
update_data:
entity.Shot.sg_status_list: fnl # (10)!
- Trigger when a
Version's
sg_status_list
field isupdated
- Action #1: set the Task status
- Only trigger when sg_status_list is changed to
fnl
specifically. - Update all
Tasks
that match theupdate_filters
below. -
Update all Tasks where the Task's Versions include the
trigger_entity
, which in this case is the Version which was just set tofnl
.In otherwords, update the Task that contains the triggering version, or in other-otherwords, update the Version's Task.
-
The specific data to update the Task(s) with, in this case we want to also set the task
sg_status_list
tofnl
. - Action #2: set the Shot status
- Instead of updating the
Shot
entity directly and choosing the correct Shot through filters (like we did for Tasks), we're going to updateSELF
, which in this case is the triggering Version whose status changed. Either method works. - No need to have filters for
SELF
since we already knowSELF
is the specific Version that triggered this event. -
Using deep linking/dot notation, we are able to update the Version's linked Shot's Status field.
So, we're technically updating the Version, but we're updating a deep linked field that is actually the Version's Shot status.
Set sg_date_dropped_in
time when sg_di_dropped
checkbox is changed¶
webhooks:
update_entity:
triggers:
Shot/update/sg_di_dropped: # (1)!
- description: set date dropped in when di dropped is checked
trigger_values:
- true # (2)!
update_entity: SELF
update_filters: null
update_data:
sg_date_dropped_in: $datetime # (3)!
- description: clear date dropped in when di dropped is unchecked
trigger_values:
- false # (4)!
update_entity: SELF
update_filters: null
update_data:
sg_date_dropped_in: None # (5)!
- Trigger when a
Shot's
sg_di_dropped
field isupdated
- Action #1: when checkbox is checked (set to
true
) - Set Shot's
sg_date_dropped_in
field to current time. - Action #2: when checkbox is unchecked (set to
false
) - Set Shot's
sg_date_dropped_in
field to None (blank)
Set previous versions to outdated
when version is latest
¶
webhooks:
update_entity:
triggers:
Version/update/sg_status_list: # (1)!
- description: set old versions outdated when a version is set to latest
trigger_values:
- lav # (2)!
update_entity: Version
update_filters: # (3)!
- - entity
- is
- $trigger_entity.entity
- - sg_task
- is
- $trigger_entity.sg_task
- - sg_status_list
- is
- lav
update_data:
sg_status_list: outv # (4)!
- Trigger when a
Version's
sg_status_list
field isupdated
- Only trigger when the new status value is
lav
(Latest) - Find all Versions of the same Entity Link (e.g. Shot) and Task as the triggering Version and also have the status
lav
(Latest) - Set those Versions statuses to
outv
(Outdated)
Add vendor
to a Shot when it's set on a Version¶
webhooks:
update_entity:
triggers:
Version/update/user: # (1)!
- description: add vendor to shot when it's set on version
trigger_values: null
update_entity: SELF
update_filters: null
update_data:
entity.Shot.sg_vendor_groups: # (2)!
- $new_value
multi_entity_update_modes:
entity.Shot.sg_vendor_groups: add # (3)!
- description: remove vendor from shot when it's removed from version
trigger_values: [null] # (4)!
update_entity: SELF
update_filters: null
update_data:
entity.Shot.sg_vendor_groups: # (5)!
- $old_value
multi_entity_update_modes:
entity.Shot.sg_vendor_groups: remove # (6)!
- Trigger when a
Version's
user
field isupdated
- Update the linked Shot's
sg_vendor_groups
field with the new_value -
Since
sg_vendor_groups
is a multi-entity field, we specify that we want toadd
$new_value
to the list of sg_vendor_groups.Without this it would default to
set
, which would replaces all sg_vendor_groups with only$new_value
-
If
$new_value
is null (a vendor was removed from a Version), we need to remove the vendor from the Shot as well. - This time, we update
sg_vendor_groups
with theold_value
- ...and set
multi_entity_update_mode to
remove, which will remove
$old_value` from the current sg_vendor_groups.
Final Shot when all Tasks are final¶
This example is a little tricky, we want to update the triggering Task but only if all tasks are final. So, we filter on the triggering task's id
, which will only ever match the triggering Task, but we also add additional filters to check fields of other linked entities. So, our filters will only ever match either the triggering Task, or nothing (in which case no updates occur.)
webhooks:
update_entity:
triggers:
Task/update/sg_status_list: # (1)!
- description: final shot when all tasks are final
trigger_values: ["fin", "omt"] # (2)!
update_entity: Task
update_filters: [
["id", "is", $trigger_entity.id], # (3)!
[
"entity.Shot.tasks.Task.sg_status_list", # (4)!
"not_in",
["wtg", "ip", "hld"], # (5)!
],
]
update_data: { "entity.Shot.sg_status_list": "fin" } # (6)!
- Trigger when a
Task's
sg_sg_status_list
field isupdated
-
Action #1: when status is set to
fin
oromt
(When a Task is omitted, we still want to final the Shot if all the other Tasks are final.)
-
Match the Task with the same id as our triggering entity. Normally you could just use
SELF
, but in this case we need to add additional filters on the next line. - We know the triggering task's status is
fin
oromt
, but we need to check the statuses for all tasks that belong to this Task's shot. We can do that with this deep linked field, which finds the triggering Task's linked Shot, then that Shot's tasks (plural), and makes sure none of the Tasks' statuses are in the list. -
If no task statuses are in this list, we assume they're all
fin
oromt
. We have to usenot_in
instead ofin
.If we checked if that status was
in
[fin, omt]
instead, it would match if any of the Shot's tasks are final, but we need it to only match if all of the Shot's tasks are final, so we have to do this negative check. -
Update the matched task (if any)'s Shot status to
fin
Debugging¶
There are many places where a webhook can go wrong. The first step is to check the Webhooks page in Shotgrid to make sure the Webhook triggered and was sent to our system.
todo: screenshot
The response
tab should say "Webhook delivery received." It it doesn't, then our system did not accept the webhook at all. Possibly the Webhook URL is misformed, or some other backend error occurred.
todo: screenshot
Once we are sure our system received the webhook, we can check for more details in the Logfire logs, or back in Shotgrid, view the result in the Acknowlegement
section of the Request
tab:
todo: screenshot
Configuration or other errors will usually display here in this Acknowledgement
for convenience.
-
Flow Production Tracking Webhooks Guide - When do Lifecycle Events Occur? ↩
-
Flow Production Tracking Webhooks Guide - Creating a Webhook ↩