How to ensure "Send HTTP request" Flow action sends HMAC header for authentication?

I have a Remix app with a custom endpoint that I want Flow to send a POST request to, but I’m unable to authenticate the request from Flow’s “Send HTTP request” action which I created and enabled using the Flow admin gui.

My endpoint is public and I haven’t added any headers to the Flow action. The Flow action body is plain text and right now just says “hello world” since I’m stuck on authentication. I did try adding the Content-Type: application/json header and made the body into JSON, but the result is the same.

I debugged by logging the request headers and I don’t see an HMAC header. I’m running the Shopify CLI app dev and the Flow action URL is set to my Cloudflare tunnel address (which I update when needed) + endpoint route. I know my endpoint hits successfully because the console.log() before authentication works fine, but I just can’t work out the authentication bit.

What am I doing wrong?

The error I see in my dev console is:

[shopify-app/INFO] Authenticating flow request
[shopify-app/ERROR] Received an invalid flow request | {reason: missing_hmac}

Here’s what I’m trying:

import { authenticate } from "../shopify.server";

export const action = async ({ request }) => {
  console.log('Test!'); // <------ this outputs in my dev console
  const {admin, payload} = await authenticate.flow(request);

  // nothing after this line logs to console and I see the missing_hmac error above

  const query = await admin.graphql(
    `#graphql
      query {
        customer(id: "gid://shopify/Customer/7501057097902") {
          locations: metafield(namespace: "custom", key: "customer_locations") {
            value
          }
        }
  }`);

  const { data } = await query.json();
  console.log(data);
  
  // will do more stuff here

  return new Response();
};

You would use this approach and HMAC if you were building an action for your app. If it’s coming from Send HTTP request there won’t be an HMAC, as it’s designed to connect to any API.

So you could just remove the authenticate part. If you need auth, you would have to build your own.

Hi there, are you developing a Flow action extension or are you creating a general purpose HTTP endpoint that you’d like Flow to call via the “Send HTTP request” action?

If you’re developing a Flow action extension, there’s no need to use the “Send HTTP request” action within a workflow. You can use the action from your app directly within the workflow. It will appear under your app’s name when adding a new step to the workflow. When the workflow is activated, resulting runs of that workflow will send a request to the endpoint defined in the extension with the appropriate HMAC headers, which authenticate.flow will extract and verify.

If you are developing a general purpose HTTP endpoint, then the authentication is up to you and there’s no need to use authenticate.flow.

Hope this helps!

Thanks,
Ryan

Gotcha, thank you for that.

Is there a way to run an admin query as part of a recurring task like a cron job or service worker without authenticating? What would be the best way to do that?

You might need to be more specific. Flow has a “Scheduled time” trigger which is cron-like and “Get data” actions such as “Get product data” that query Admin API data