App with function that runs every hour

Topic summary

A developer is building a Shopify app (using React/Remix template, hosted on Heroku) that needs to automatically update product metafields every hour by looping through all products and modifying data based on retrieved information.

Initial Solution Proposed:

  • Use an offline access token for authentication
  • Implement Heroku Scheduler or Cron To Go to trigger hourly jobs
  • Create a webhook endpoint in the Remix app to handle scheduled requests
  • Validate webhook requests for security

Current Issue:
The developer successfully created a function that works locally, but when deployed to Heroku and triggered via Cron To Go, the database doesn’t update despite receiving a “successfully updated” response. The webhook route configuration appears to be the problem.

Alternative Approach Suggested:
Create a Flow Action extension within the app, then use Shopify Flow with a scheduled trigger to execute the action. This method allows authentication via authenticate.flow(request) to instantiate the GraphQL Admin API client for administration tasks.

Status: The issue remains unresolved, with the developer seeking guidance on proper webhook route configuration.

Summarized with AI on October 25. AI used: claude-sonnet-4-5-20250929.

Hi there! I was hoping somebody could give me some guidance on this matter.

I am developing an app. The app is simple -it (1) loops through all products, (2) grabs several pieces of information about each product, and (3) based on that information updates a specific product metafield.

So far, so good. I’ve done this part.

What I need to do now is for the app is to go through this process on an hourly basis - it should be able to run through steps 1-3 in the background, without someone having to open up the app and press the ‘update’ button.

Can anyone think of a way to do this?

For context, I am developing this app using the React/Remix template.

Hey @gut_und_gunstig

Sure thing - be sure to use an offline access token. Scheduling the job to run every hour is different for each platform/host - who are you using?

Hey @SBD thanks very much for your response. The app is hosted on Heroku currently. What would be the process with that? Thanks :slightly_smiling_face:

Try this one :slightly_smiling_face: https://devcenter.heroku.com/articles/scheduler

@SBD thanks very much!

I have one further question. The app I’m building has been built with the React/Remix template. As far as I can tell, there doesn’t seem to be a straightforward way to run background/CRON job with Remix. It doesn’t seem like CRON jobs can be done through remix routes, although I might be wrong.

Do you have any idea how I might set this up?

Hey @gut_und_gunstig

This isn’t specifically related to Remix, but rather the environment where your Remix app is running.

You could use something like this: https://devcenter.heroku.com/articles/crontogo to send a recurring webhook to your Remix app (and create a route to respond to the webhook). Don’t forget to validate that the requests come from the webhook.

Good luck!

Hey @SBD thanks so much for your guidance, I’ve followed your suggestion and got almost all of the way.

The only issue I’m facing is the setting up the route to respond to the webhook. I’ve written a function that successfully updates the database when i run it locally, but when it’s deployed to heroku and I call the function through Cron To Go scheduler, the database isn’t updated.

The function itself is fired and a ‘successfully updated’ response is received, but there’s no change to the database at all.

Can you provide any guidance as to how I would set up and configure a route to respond to the webhook?

Easiest way to do this nowadays IMHO is by creating a Flow Action (extension) within your app.

Then, you create a Flow with the Shopify Flow app with an scheduled trigger. And select, as an action, the Flow Action you created with your app.

The flow request can be authenticated in your app route to instantiate the GraphQL Admin API client like this:

export const action = async ({request}) => {
const {admin} = await authenticate.flow(request);
...
...

Which allows for you to do administration tasks within the scope of your app.