Triggers 

What is a trigger? 

Triggers in Gadget are events or conditions that initiate an action within an application. They parse external events, such as incoming webhooks or API calls, and then run your action with parameters. Default triggers are already established in many actions, such as the API endpoint trigger for integrating the action into your app's API or the Shopify data trigger that executes actions in response to Shopify webhooks.

How triggers work 

Each trigger in Gadget does two things:

1. Activates on a certain event: Each trigger is designed to execute at a specific point, determined by various conditions or events. For instance, an API endpoint trigger executes when its corresponding mutation in the GraphQL API is invoked, while a Scheduler trigger activates at pre-set time intervals like a cron job might.

2. Sends the params and trigger to the action: Upon activating, the trigger tests authorization. If successful, the action is run with the params and trigger variables parsed out by the trigger. The contents of the params object depend on the trigger, and the contents of the trigger object describe which trigger ran and why.

Types of triggers 

API endpoint trigger 

The API endpoint trigger invokes your action when an incoming API call is made to your application's API. For more on your application's API and how to make API calls, see the API Reference.

By default, most actions have an api trigger already registered. If you want to explicitly register an api trigger, you can do so by adding an api property to the triggers object in the action's options.

api/actions/example.js
JavaScript
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 api: true,
6 },
7};
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 api: true,
6 },
7};

How the API actions are run 

The API trigger runs your actions when the corresponding mutation is run in your application's generated API. When this mutation is called, the trigger assesses if the caller has permission to run the action using your application's access control.

If permitted, the action's run function is executed, passing any incoming parameters. For model actions, the resulting record is sent back to the API caller, and for global actions the return value of the run function is sent back. If any errors are thrown during processing, those errors are instead sent back to the caller.

The generated API endpoints for your API triggers can be called using the api object within your application, or using the React hooks from @gadgetinc/react hooks library, or any other GraphQL client.

API endpoint trigger params 

The API endpoint trigger validates that incoming parameters match the expected types for the action, and then passes the params to the action.

For model actions, API triggers add automatic params for each field on the model. For global actions, there are no params by default.

For more on adding parameters to actions, see the action guide.

API endpoint trigger trigger object 

When an action is invoked via an API call, the passed trigger object will look like this:

an example API trigger object
json
1{
2 "type": "api",
3 "mutationName": "updateWidget",
4 "rootAction": "update",
5 "rawParams": {
6 "id": "123",
7 "widget": {
8 "title": "New Widget Title",
9 "inventoryCount": 10
10 }
11 }
12}
  • type: will always be set to api.
  • mutationName: the string name of the mutation called in the API.
  • rootAction: the API identifier of the action triggered by the mutation.
  • rawParams: the params passed to this API call.

Scheduler trigger 

The Scheduler trigger invokes your action at a regular interval. For example, scheduled actions can be used to send out periodic emails, build database aggregates, or sync data from external systems.

The Scheduler trigger has a scheduler property which describes how often the action should be run, and at what specific times. For example, you can create a Schedule that runs every day at 10:00 AM UTC:

api/actions/example.js
JavaScript
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 scheduler: [{ every: "day", at: "10:00 UTC" }],
6 },
7};
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 scheduler: [{ every: "day", at: "10:00 UTC" }],
6 },
7};

Schedule triggers also support multiple individual schedules, and will invoke your action at each time specified by any included schedule. For example, we can set up a scheduler to run an action every day at midnight UTC, as well as every Wednesday at noon:

api/actions/example.js
JavaScript
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 scheduler: [
6 { every: "day", at: "00:00 UTC" },
7 {
8 every: "week",
9 on: "Wednesday",
10 at: "12:00 UTC",
11 },
12 ],
13 },
14};
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 scheduler: [
6 { every: "day", at: "00:00 UTC" },
7 {
8 every: "week",
9 on: "Wednesday",
10 at: "12:00 UTC",
11 },
12 ],
13 },
14};

Schedule triggers can also be expressed using cron syntax, which is a more powerful way to define schedules. For example, the following scheduler options will run an action every day at midnight UTC:

api/actions/example.js
JavaScript
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 scheduler: [{ cron: "0 0 * * *" }],
6 },
7};
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 scheduler: [{ cron: "0 0 * * *" }],
6 },
7};

The minimum interval supported by the scheduler trigger is once a minute.

How scheduled actions are run 

When you add a Scheduler trigger, Gadget's internal scheduler starts a ticking clock. When the time arrives for a scheduled action to run, Gadget invokes the global action. Unlike api triggers, no params will be passed to the action.

Overlapping executions 

If a scheduled action is still running when the next scheduled invocation arrives, that next invocation will be skipped. For example, if an action is scheduled to run every minute and it takes 3.5 minutes to complete, the executions that were scheduled during that 3.5-minute window will be skipped.

Schedule trigger params 

The Scheduler trigger passes an empty params object when it invokes an action.

If you need to know the current time for executing your action, you can use new Date().

Schedule trigger trigger object 

The Scheduler trigger passes a simple trigger object describing the trigger type:

json
{
"type": "scheduler"
}

Shopify data trigger 

The Shopify data trigger executes model actions when:

  • Shopify sends a webhook to your Gadget application
  • when a missed webhook is detected by Gadget during reconciliation
  • or when a sync is run and data differences are detected

When this trigger runs, it:

  1. parses the payload from Shopify, performing HMAC validation on webhooks to ensure authenticity
  2. transforms the payload into appropriate params for each record described in the payload
  3. executes the action for each record in the payload, including nested records

Shopify data triggers can also be added to global actions to process webhooks there. For more information on how to use Shopify data triggers in global actions check out the guide here. You can include a shopify trigger in Shopify models, but not other models.

Shopify data triggers look like this within your action's options:

api/actions/example.js
JavaScript
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 shopify: {
6 webhooks: ["products/create"],
7 },
8 },
9};
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 shopify: {
6 webhooks: ["products/create"],
7 },
8 },
9};

To reduce boilerplate, Shopify models don't need to include explicit shopify triggers in their options -- Gadget will apply the correct triggers by default. It's fine to include a shopify trigger in Shopify models if you want to customize the options, but it's not required.

Shopify data trigger params 

For model actions, the Shopify data trigger pulls out the right parameters for the current record from the payload and adjusts the keys to have consistent JavaScript style-casing. For example, when a webhook for a product/create webhook arrives, Gadget chops up the payload into the chunk to create params for the root-level product, and then another set of params for each shopifyProductVariant record described in the payload. For this example webhook on the shopifyProduct model, the params object will look like this:

example model action Shopify Webhook trigger params
json
1{
2 "id": "12345",
3 "shopifyProduct": {
4 "title": "Example T-Shirt",
5 "tags": ["example", "t-shirt"],
6 "publishedAt": "2024-01-01T00:00:00Z",
7 "productCategory": {
8 "id": "12345",
9 "name": "Shirts"
10 }
11 // ... etc
12 }
13}

and for the shopifyProductVariant model, the params object will look like this:

example model action Shopify Webhook trigger params
json
1{
2 "id": "5678",
3 "shopifyProductVariant": {
4 "title": "Example T-Shirt",
5 "sku": 10,
6 "price": 10.99,
7 "inventoryPolicy": "continue",
8 "fulfillmentService": "manual"
9 // ... etc
10 }
11}

For global actions, the incoming Shopify webhook payload is delivered as the params unchanged. For a product/create webhook, the params object will look like this:

example global action Shopify Webhook trigger params
json
1{
2 "topic": "products/create",
3 "payload": {
4 "admin_graphql_api_id": "gid://shopify/Product/788032119674292922",
5 "body_html": "An example T-Shirt",
6 "created_at": null,
7 "handle": "example-t-shirt",
8 "id": 788032119674292922
9 // ... etc
10 }
11}

The params delivered for each different webhook topic are different, and they can change when Shopify makes changes.

Shopify data trigger trigger object 

When a Shopify data trigger invokes an action, it will pass a trigger describing the event that caused the action to run. For the Shopify data trigger, this can be one of two events:

  • a webhook was received
  • a sync detected differences

You can detect which type of event occurred by checking the type property of the trigger object:

api/models/shopifyProduct/actions/create.js
JavaScript
1export const onSuccess: ActionOnSuccess = async ({ trigger }) => {
2 if (trigger.type == "shopify_sync") {
3 // do something because a sync happened
4 } else {
5 // do something because a webhook was received
6 }
7};
1export const onSuccess: ActionOnSuccess = async ({ trigger }) => {
2 if (trigger.type == "shopify_sync") {
3 // do something because a sync happened
4 } else {
5 // do something because a webhook was received
6 }
7};
Example webhook trigger object 

When a Shopify webhook is received by your Gadget application, the trigger object passed to your action will look like this:

json
1// An example Shopify Webhook trigger
2{
3 "type": "shopify_webhook",
4 "topic": "products/update",
5 "payload": {
6 "id": 788032119674292900,
7 "title": "Example T-Shirt",
8 "body_html": "An example T-Shirt",
9 "vendor": "Acme",
10 "product_type": "Shirts",
11 "created_at": null,
12 "handle": "example-t-shirt"
13 // ... etc matching Shopify's format exactly
14 },
15 "shopId": "shop123",
16 "retries": 0
17}
  • type: will always be set to shopify_webhook
  • topic: the string representing the topic of the incoming webhook from Shopify, like products/update or orders/create
  • payload: the raw incoming payload from Shopify, which includes all the data sent by the webhook unchanged
  • shopId: the identifier for the Shopify store that received the webhook
  • retries: the number of times this webhook has been retried

The complete payload of the webhook received is accessible within the trigger object that is passed to your action code.

Example sync trigger object 

When a sync of a particular Shopify shop is run and detects differences, the trigger object passed to your action will look like this:

An example Shopify Sync trigger
json
1{
2 "type": "shopify_sync",
3 "shopId": "123456",
4 "apiVersion": "2023-01",
5 "shopifyScopes": ["read_products", "write_products"],
6 "syncId": "1",
7 "syncSince": null,
8 "models": ["shopifyShop", "shopifyProduct"],
9 "force": false,
10 "startReason": undefined // will be "scheduled" if Action ran via daily sync
11}
  • type: Will always be set to shopify_sync
  • shopId: The identifier of the Shopify shop being synced
  • apiVersion: The version of the Shopify API being used for the sync
  • shopifyScopes: The available OAuth scopes of the Shopify shop being synced
  • syncId: The identifier of the sync record tracking the state of this sync (optional, only available if set)
  • syncSince: The specified date range of this sync (optional, only set if specified when the sync was started)
  • models: The list of model API identifiers that this sync will work on
  • force: Indicates if this sync is being run in 'force' mode, which will always run actions even if the 'updated_at' timestamps match between Gadget and Shopify
  • startReason: The string describing the reason why this sync was started (optional, only set if specified when the sync began)

Shopify customer account login trigger 

This trigger fetches customer data from Shopify when customer account authentication is enabled in Gadget and a Shopify customer makes a request to a Gadget app from a customer account UI extension.

When the request is made from a customer account UI extension, the customer is assigned a unique session record that is linked to their shopifyCustomer model record. If this shopifyCustomer record does not exist in Gadget, this trigger will be activated to fetch the customer data from Shopify so the customer can be linked to their current session.

This trigger is automatically added to the shopifyCustomer model's create action when customer account authentication is enabled in Gadget. If customer account authentication is disabled, this trigger will be automatically removed.

BigCommerce webhook trigger 

The BigCommerce webhook trigger allows you to run global actions in response to BigCommerce webhooks.

When this trigger runs, it:

  1. Parses the payload from BigCommerce, following the BigCommerce best practices for webhook security
  2. Adds the raw webhook payload to params
  3. Executes the action

When you add a BigCommerce webhook trigger to a global action, Gadget will automatically register the webhook. You can specify which BigCommerce webhooks should trigger your action by adding a bigcommerce property to the triggers object in the action's options, or by using the Gadget editor to add the trigger and select the webhook topics.

This is what a BigCommerce webhook trigger looks like in your action's options:

api/actions/handleProductCreatedWebhook.js
JavaScript
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 api: false,
6 bigcommerce: {
7 webhooks: ["store/product/created"],
8 },
9 },
10};
1import type { ActionOptions } from "gadget-server";
2
3export const options: ActionOptions = {
4 triggers: {
5 api: false,
6 bigcommerce: {
7 webhooks: ["store/product/created"],
8 },
9 },
10};

BigCommerce webhook trigger params 

BigCommerce webhook payloads contain minimal information about the store and event. Gadget will pull out the important information from the payload and pass it to the action as params. You can then use the included BigCommerce API client to fetch the full resource data in the action.

For example, this is what the params object might look like for a store/product/created webhook:

example of a params payload for a store/product/created webhook
json
{
"id": 1,
"storeHash": "<your-store-hash>",
"type": "product"
}

The params delivered for each different webhook topic are different, and they can change when BigCommerce makes changes.

BigCommerce webhook trigger trigger object 

The trigger object passed to your action contains the entire webhook payload, as well as additional information about the trigger itself.

This is what the trigger object might look like for a store/product/created webhook:

example of a trigger object for a store/product/created webhook
json
1{
2 "createdAt": 1723578525,
3 "data": {
4 "id": 1,
5 "type": "product"
6 },
7 "hash": "<your-hash-value>",
8 "retries": 0,
9 "scope": "store/product/created",
10 "storeHash": "<your-store-hash>",
11 "type": "bigcommerce_webhook"
12}

For BigCommerce webhook triggers, the trigger object will always contain the following properties:

  • type: will always be set to bigcommerce_webhook
  • scope: the string representing the topic of the incoming webhook from BigCommerce, like store/product/created or store/order/updated
  • storeHash: the hash of the BigCommerce store that received the webhook
  • hash: the hash value of the webhook payload
  • retries: the number of times this webhook has been retried
  • createdAt: the timestamp of when the webhook was created
  • data: the raw incoming payload from BigCommerce, which includes all the data sent by the webhook unchanged

Google OAuth sign up trigger 

This trigger is part of the authentication process that integrates Google as an OAuth provider in your application. The entire profile payload from Google plus the additional data from the user model to the action to receive the necessary information from the user's Google profile.

Google OAuth sign up trigger params 

When a new user signs up using Google OAuth, the trigger will run your action with params describing the new user, like this:

example Google OAuth Sign Up params
json
1{
2 "user": {
3 "email": "[email protected]",
4 "emailVerified": true,
5 "firstName": "Giz",
6 "googleImageUrl": "https://gmail.com/some/image.png",
7 "googleProfileId": "113836975668244786030",
8 "lastName": "Mo",
9 "roles": ["signed-in"]
10 }
11}

These params are derived from the Google OAuth callback data passed by Google and adjusted by the trigger to match the fields of the user model. The raw data returned by Google is available in the trigger object.

Google OAuth sign up trigger trigger 

The trigger object contains the raw data returned by Google at user object.

example Google OAuth Sign Up trigger
json
1{
2 "type": "google_oauth_signup",
3 "user": {
4 "email": "[email protected]",
5 "email_verified": true,
6 "family_name": "Mo",
7 "given_name": "Giz",
8 "hd": "gadget.dev",
9 "name": "Giz Mo",
10 "picture": "https://gmail.com/some/image.png",
11 "sub": "113836975668244786030"
12 }
13}

Default email/password authentication triggers 

Every Gadget web app template by default comes with several out-of-the-box authentication triggers associated with the corresponding authentication actions.

The following authentication triggers although named differently all have the same behavior of the API endpoint trigger.

  • Sign up
  • Sign in
  • Verify email
  • Reset password
  • Send reset password
  • Send verify email
  • Change password

Was this page helpful?