Skip to content

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
  1. Currently the only valid webhook type is update_entity.
  2. See trigger entities
  3. The webhook will only trigger if the field has changed to one of these values.
    If None, the webhook will always trigger.
  4. The Entity type to update. If SELF, it will update the same entity that triggered the webhook.
  5. If update_entity is not SELF, these filters are used to select which specific entities of type update_entity will be updated. For filter syntax, see: Shotgrid rest-api
  6. The new values to set on the filtered entities. See update_data
  7. Each trigger can have as many action blocks as needed to peform different actions for different trigger_values or to update different entities.
  8. Optional. How to treat updates to multi-entity fields.

    Can be set, add, or remove. The default is set.

    see: Shotgrid API update documentation

  9. 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 is changed.
  • Shot/create: triggers when a Shot is created

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 is update, the value the field was changed _to
  • $old_value: when event is update, 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:
    https://app.slingshotsystems.io/api/v1/shows/XXXXXXXXXXXXXXXXXXXXXXXX/hook/sg/update_entity
    
    (where the Xs are replaced with the show's ID) Shot ID Example
  • 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

Flow Webhook Example

  • 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)!
  1. Trigger when a Version's sg_status_list field is updated
  2. Action #1: set the Task status
  3. Only trigger when sg_status_list is changed to fnl specifically.
  4. Update all Tasks that match the update_filters below.
  5. Update all Tasks where the Task's Versions include the trigger_entity, which in this case is the Version which was just set to fnl.

    In otherwords, update the Task that contains the triggering version, or in other-otherwords, update the Version's Task.

  6. The specific data to update the Task(s) with, in this case we want to also set the task sg_status_list to fnl.

  7. Action #2: set the Shot status
  8. Instead of updating the Shot entity directly and choosing the correct Shot through filters (like we did for Tasks), we're going to update SELF, which in this case is the triggering Version whose status changed. Either method works.
  9. No need to have filters for SELF since we already know SELF is the specific Version that triggered this event.
  10. 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)!
  1. Trigger when a Shot's sg_di_dropped field is updated
  2. Action #1: when checkbox is checked (set to true)
  3. Set Shot's sg_date_dropped_in field to current time.
  4. Action #2: when checkbox is unchecked (set to false)
  5. 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)!
  1. Trigger when a Version's sg_status_list field is updated
  2. Only trigger when the new status value is lav (Latest)
  3. Find all Versions of the same Entity Link (e.g. Shot) and Task as the triggering Version and also have the status lav (Latest)
  4. 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)!
  1. Trigger when a Version's user field is updated
  2. Update the linked Shot's sg_vendor_groups field with the new_value
  3. Since sg_vendor_groups is a multi-entity field, we specify that we want to add $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

  4. If $new_value is null (a vendor was removed from a Version), we need to remove the vendor from the Shot as well.

  5. This time, we update sg_vendor_groups with the old_value
  6. ...and set multi_entity_update_mode toremove, 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)!

  1. Trigger when a Task's sg_sg_status_list field is updated
  2. Action #1: when status is set to fin or omt

    (When a Task is omitted, we still want to final the Shot if all the other Tasks are final.)

  3. 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.

  4. We know the triggering task's status is fin or omt, 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.
  5. If no task statuses are in this list, we assume they're all fin or omt. We have to use not_in instead of in.

    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.

  6. 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.


  1. Flow Production Tracking Webhooks Guide - When do Lifecycle Events Occur? 

  2. Flow Production Tracking Webhooks Guide - Creating a Webhook