TutorialsCourses

Cancel a Scheduled Event in Hasura

Introduction

Hasura ships with the ability to create scheduled events, however once a scheduled event is created the /v1/query endpoint provides no way to delete it. You can cancel it from the console but that is less than ideal.

If you look at the request that is made from the console you can see it's a call the /v1/query endpoint. It turns out that deleting a scheduled event is actually an undocumented feature.

The reason why is that the scheduled event should be querying back to Hasura to decide whether or not it should still execute. This is fine in concept but not realistic if the request is being made to an endpoint you may not control.

Posting To Hasura

Generally when requesting data from Hasura you are requesting the /v1/graphql endpoint. When needing to make changes to the hasura configuration itself we need to talk to the /v1/query endpoint.

We'll create a general fetch function to post to the /v1/query endpoint. These would likely be replaced with environment variables but we'll hardcode these for now. You'll need to POST the JSON as the body, and also supply the admin secret in the headers of the request.

const postToQuery = async (body: any) => {
  const res = await fetch("http://localhost:8080/v1/query", {
    method: "POST",
    headers: {
      "X-Hasura-Admin-Secret": "your_admin_secret_here",
    },
    body: JSON.stringify(body),
  });

  return await res.json();
};

Creating a Scheduled Event

In order to create a scheduled event we will call our postToQuery function with a type which is creating a scheduled event. All the args can be found in the documentation here https://hasura.io/docs/1.0/graphql/core/scheduled-triggers/create-one-off-scheduled-event.html#creating-one-off-scheduled-event.

But the important piece for us is the comment section.

const data = await postToQuery({
  type: "create_scheduled_event",
  args: {
    webhook: "https://google.com",
    schedule_at: "2021-02-10T10:00:00Z",
    payload: {},
    retry_conf: {
      num_retries: 3,
      timeout_seconds: 120,
      tolerance_seconds: 21675,
      retry_interval_seconds: 12,
    },
    comment: "Some_cool_id_you_created",
  },
});

Unforunately rather than returning an id to the scheduled event it just returns a successful message. So we aren't able to cancel by the id.

{
	"message": "success"
}

However inserting a comment can actually be more beneficial to us. You can create a unique comment and leverage that as an id for canceling. If you were texting a person associated with a specific appointment rather than storing an id from hasura you'll be able to craft a comment id.

Canceling a Scheduled Event

Now that we have an event with a comment called Some_cool_id_you_created we can treat this as our id to find the specific event we want to cancel. The Hasura console provides the necessary structure to send to /v1/query to cancel a scheduled event.

It uses the id and looks something like

{
    type: "delete",
    args: {
      table: {
        name: "hdb_scheduled_events",
        schema: "hdb_catalog",
      },
      where: {
        id: {
          $eq: "123456789",
        },
      },
    },
  }

Notice that is resembles a normal Hasura query but slightly different. It's querying for an id in a table to delete.

We can modify this to delete now based off of our comment. We change the id to comment and can now pass it our known comment that we created and use that as the mechanism to delete the scheduled trigger.

export const cancelScheduledEvent = (id) => {
  return postToQuery({
    type: "delete",
    args: {
      table: {
        name: "hdb_scheduled_events",
        schema: "hdb_catalog",
      },
      where: {
        comment: {
          $eq: id,
        },
      },
    },
  });
};

Then to call it we pass it our comment id Some_cool_id_you_created and it will be cancelled.

cancelScheduledEvent("Some_cool_id_you_created");