Webhook challenge verification failing "URL validation failed. Try again later."

I’m trying to verify a webhook listener that i’m setting up in a google apps script. I’ve cross referenced the hashing function’s output to that of the example node.js project, and it looks identical. Is there anything obvious i’m missing? I triple checked the secret token is correct, too.

const ZOOM_WEBHOOK_SECRET_TOKEN = "my_secret_token";

function doPost(e) {
  // Log the incoming payload
  console.log(JSON.stringify(e));

  const body = e.postData.contents; // Raw request body
  Logger.log(`Received: ${body}`);
  const data = JSON.parse(body); // Parsed request body

  // Check if this is a challenge (URL validation)
  if (data.event === "endpoint.url_validation") {
    const plainToken = data.payload.plainToken;

    // Hash the plainToken with the secret token (HMAC SHA-256)
    const encryptedToken = hashPlainToken(plainToken);

    // Create the response JSON object
    const responseJson = {
      plainToken: plainToken,
      encryptedToken: encryptedToken
    };

    // Respond with the encrypted token in JSON format
    Logger.log(`Sending back: ${JSON.stringify(responseJson)}`);
    return ContentService.createTextOutput(JSON.stringify(responseJson))
      .setMimeType(ContentService.MimeType.JSON);
  }

  // Respond to Zoom with a 200 OK
  return ContentService.createTextOutput("OK");
}

// Function to hash the plainToken with your secret token (HMAC SHA-256)
function hashPlainToken(plainToken) {
  const hash = Utilities.computeHmacSha256Signature(plainToken, ZOOM_WEBHOOK_SECRET_TOKEN);

  // Convert the hash to a hex string
  const hashHex = hash.map(byte => (byte < 0 ? byte + 256 : byte).toString(16).padStart(2, "0")).join("");

  return hashHex;
}

This is incredibly tough to debug thanks to absolutely no feedback in the zoom validation flow (no helpful error messages).

Hi @afletcher
Thanks for reaching out to us and welcome to the Zoom Developer Forum
From looking at your code, I dont where you are checking the signature you get in the request headers with the one you have to create

that might be the piece you are missing, you can reference that on line 24