Configure a Trigger

Triggers allow you to trigger webhooks when certain types of data are sent from your machine to the cloud, or when the your machine parts connect to Viam. For example, you can configure a trigger to send you a notification when your robot’s sensor collects a new reading. Viam provides three trigger types depending on the event you want to trigger on:

  • Data has been synced to the cloud: trigger when data from the machine is synced
  • Part is online: trigger continuously at a specified interval while the machine part is online
  • Part is offline: trigger continuously at a specified interval while the machine part is offline

To configure a trigger:

  1. Go to the CONFIGURE tab of your machine on the Viam app. Click the + (Create) button in the left side menu and select Trigger.

    The Create menu with Trigger at the bottom of the list of options.
  2. Name the trigger and click Create.

  3. Select trigger Type. For the respective type, configure the respective attributes:

Select the data types for which the Trigger should send requests. Whenever data of the specified data types is ingested, a POST request will be sent.

Edit the Time between notifications attribute to set the interval at which this trigger will send GET requests when the part is online.

Edit the Time between notifications attribute to set the interval at which this trigger will send GET requests when the part is offline.

  1. Replace the URL value with the URL of your cloud function or lambda.

    The trigger configured with an example URL in the Viam app.

To configure your trigger by using JSON mode instead of Builder mode, paste one of the following JSON templates into your JSON config. "triggers" is a top-level section, similar to "components" or "services".

  "triggers": [
    {
      "name": "<trigger name>",
      "event": {
        "type": "part_data_ingested",
        "data_ingested": {
          "data_types": ["binary", "tabular", "file"]
        }
      },
      "notifications": [
        {
          "type": "webhook",
          "value": "https://1abcde2ab3cd4efg5abcdefgh10zyxwv.lambda-url.us-east-1.on.aws",
          "seconds_between_notifications": <number of seconds>
        }
      ]
    }
  ]
  "triggers": [
    {
      "name": "<trigger name>",
      "event": {
        "type": "part_online"
      },
      "notifications": [
        {
          "type": "webhook",
          "value": "<https://1abcde2ab3cd4efg5abcdefgh10zyxwv.lambda-url.us-east-1.on.aws>",
          "seconds_between_notifications": <number of seconds>
        }
      ]
    }
  ]
  "triggers": [
    {
      "name": "<trigger name>",
      "event": {
        "type": "part_offline"
      },
       "notifications": [
        {
          "type": "webhook",
          "value": "<https://1abcde2ab3cd4efg5abcdefgh10zyxwv.lambda-url.us-east-1.on.aws>",
          "seconds_between_notifications": <number of seconds>
        }
       ]
    }
  ]
{
  "components": [
    {
      "name": "local",
      "model": "pi",
      "type": "board",
      "namespace": "rdk",
      "attributes": {},
      "depends_on": []
    },
    {
      "name": "my_temp_sensor",
      "model": "bme280",
      "type": "sensor",
      "namespace": "rdk",
      "attributes": {},
      "depends_on": [],
      "service_configs": [
        {
          "type": "data_manager",
          "attributes": {
            "capture_methods": [
              {
                "method": "Readings",
                "additional_params": {},
                "capture_frequency_hz": 0.017
              }
            ]
          }
        }
      ]
    }
  ],
  "triggers": [
    {
      "name": "trigger-1",
      "event": {
        "type": "part_data_ingested",
        "data_ingested": {
          "data_types": ["binary", "tabular", "file"]
        }
      },
      "notifications": [
        {
          "type": "webhook",
          "value": "<https://1abcde2ab3cd4efg5abcdefgh10zyxwv.lambda-url.us-east-1.on.aws>",
          "seconds_between_notifications": 0
        }
      ]
    }
  ]
}

The following attributes are available for triggers:

NameTypeRequired?Description
namestringRequiredThe name of the trigger
eventobjectRequiredThe trigger event object:
  • type: The type of the event to trigger on. Options: "part_online", "part_offline", "part_data_ingested".
  • data_types: Required with type "part_data_ingested". The data types that trigger the event. Options: "binary", "tabular", "file", "unspecified".
notificationsobjectRequiredThe notifications object:
  • type: The type of the notification. Options: "webhook".
  • value: The URL to send the request to.
  • seconds_between_notifications: The interval between notifications in seconds.
  1. Write your cloud function or lambda to process the request from viam-server. You can use your cloud function or lambda to interact with any external API such as, for example, Twilio, PagerDuty, or Zapier. The following example function prints the received headers:

    import functions_framework
    import requests
    import time
    
    @functions_framework.http
    def hello_http(request):
      payload = {
        "Org-ID": request.headers['org-id'] if 'org-id' in request.headers else 'no value',
        "Location-ID": request.headers['location-id'] if 'location-id' in request.headers else 'no value',
        "Part-ID": request.headers['part-id'] if 'part-id' in request.headers else 'no value',
        "Robot-ID": request.headers['robot-id'] if 'robot-id' in request.headers else 'no value',
        "Component-Type": request.headers['component-type'] if 'component-type' in request.headers else 'no value',
        "Component-Name": request.headers['component-name'] if 'component-name' in request.headers else 'no value',
        "Method-Name": request.headers['method-name'] if 'method-name' in request.headers else 'no value',
        "Min-Time-Received": request.headers['min-time-received'] if 'min-time-received' in request.headers else 'no value',
        "Max-Time-Received": request.headers['max-time-received'] if 'max-time-received' in request.headers else 'no value',
    
       "Data-Type": request.args['data_type'] if 'data_type' in request.args else 'no value'
      }
    
      print(payload)
    
      return 'Received headers: {}'.format(payload)
    

Returned headers

When a trigger occurs, Viam sends a HTTP request to the URL you specified for the trigger:

Trigger typeHTTP Method
part_data_ingestedPOST
part_onlineGET
part_offlineGET

The request includes the following headers:

Header KeyDescription
Part-IDThe part of the machine that triggered the request.
Robot-IDThe machine that triggered the request.
Location-IDThe location of the machine that triggered the request.
Org-IDThe organization that triggered the request.
Component-TypeThe type of component for which data was ingested. Only for part_data_ingested triggers.
Component-NameThe name of the component for which data was ingested. Only for part_data_ingested triggers.
Method-NameThe name of the method from which data was ingested. Only for part_data_ingested triggers.
Min-Time-ReceivedIndicates the earliest time a piece of data was received.
Max-Time-ReceivedIndicates the latest time a piece of data was received.

Next steps

To see an example project that uses triggers to send email notification, see the Monitor Job Site Helmet Usage with Computer Vision tutorial.

Have questions, or want to meet other people working on robots? Join our Community Discord.

If you notice any issues with the documentation, feel free to file an issue or edit this file.