Skip to content

Instantly share code, notes, and snippets.

@ikbelkirasan
Last active May 16, 2024 20:51
Show Gist options
  • Save ikbelkirasan/601dd8a51f458bf09d5ce44a102b9fd0 to your computer and use it in GitHub Desktop.
Save ikbelkirasan/601dd8a51f458bf09d5ce44a102b9fd0 to your computer and use it in GitHub Desktop.
Find the zap that matches a webhook URL.
{
const getNodes = zap => {
let nodes = [];
for (let nodeId in zap.nodes) {
const node = zap.nodes[nodeId];
nodes.push(node);
}
return nodes;
};
const getZapNodes = async zapId => {
const response = await fetch(
`https://zapier.com/api/v3/zaps/${zapId}/nodes`
);
const { objects: nodes } = await response.json();
return nodes;
};
const openZap = (zapId, nodeId) => {
const a = document.createElement("a");
a.target = "_blank";
a.href = `https://zapier.com/app/editor/${zapId}/nodes/${nodeId}`;
a.click();
};
const fetchAccounts = async () => {
const response = await fetch("https://zapier.com/api/v3/accounts");
const { objects: accounts } = await response.json();
return accounts;
};
const fetchZaps = async accountId => {
const response = await fetch(
`https://zapier.com/api/v3/zaps?account_id=${accountId}`
);
const zaps = await response.json();
return zaps;
};
const getAllZaps = async () => {
const accounts = await fetchAccounts();
const allZaps = [];
for (const accountIndex in accounts) {
const account = accounts[accountIndex];
const { objects: zaps } = await fetchZaps(account.id);
allZaps.push(...zaps);
}
return allZaps;
};
const getZapFromWebhookId = async (zapId, webhookId) => {
const nodes = await getZapNodes(zapId);
const webhookZap = nodes.find(obj => {
return obj.code === webhookId;
});
return webhookZap;
};
const findWebhooks = zap => {
const nodes = getNodes(zap);
const webhookNodes = nodes.filter(node => {
return node["selected_api"] === "WebHookAPI";
});
return webhookNodes.map(node => {
return {
...node,
zapId: zap.id
};
});
};
const getWebhooks = zaps => {
const webhookZaps = [];
for (let zapId in zaps) {
const zap = zaps[zapId];
webhookZaps.push(...findWebhooks(zap));
}
return webhookZaps;
};
const parseWebhookUrl = webhookUrl => {
const regex = /https\:\/\/hooks\.zapier\.com\/hooks\/catch\/(\w+)\/(\w+)\/?/;
const matches = regex.exec(webhookUrl);
const [, accountId, webhookId] = matches;
return {
accountId,
webhookId
};
};
const findZapForWebhookUrl = async webhookUrl => {
const zaps = await getAllZaps();
const webhookZaps = getWebhooks(zaps);
const { webhookId } = parseWebhookUrl(webhookUrl);
for (const webhookZapIndex in webhookZaps) {
const webhookZap = webhookZaps[webhookZapIndex];
const zap = await getZapFromWebhookId(webhookZap.id, webhookId);
if (zap) {
return zap;
}
}
};
async function run(webhookUrl) {
console.log(
"⌛ Looking for the zap that matches your webhook URL. Please wait..."
);
const zap = await findZapForWebhookUrl(webhookUrl);
if (!zap) {
console.error("❌ Could not find the zap");
return false;
}
console.log(`⚡ Found the zap:`, `https://zapier.com/app/editor/${zap.id}`);
}
// 👇 Paste your webhook URL here.
run("https://hooks.zapier.com/hooks/catch/1808443/ou2v4ax/");
}
@yamov
Copy link

yamov commented May 16, 2024

Thanks for the script 🙏. It's insane that Zapier doesn't let finding zaps by hook urls out of the box 🤯

I was getting errors trying to run the original script. Here's the updated version that worked for me. Just in case anyone needs it later.

{
  const fetchZapNodes = async (zapId) => {
    const response = await fetch(`https://zapier.com/api/v3/zaps/${zapId}/nodes`)
    const { objects: nodes } = await response.json()
    return nodes ?? []
  }

  const fetchAccounts = async () => {
    const response = await fetch('https://zapier.com/api/v3/accounts')
    const { objects: accounts } = await response.json()
    return accounts
  }

  const fetchZaps = async (accountId) => {
    const response = await fetch(`https://zapier.com/api/v3/zaps?account_id=${accountId}`)
    const zaps = await response.json()
    return zaps
  }

  const getAllZaps = async () => {
    const accounts = await fetchAccounts()
    const allZaps = []
    for (const account of accounts) {
      const { objects: zaps } = await fetchZaps(account.id)
      allZaps.push(...zaps)
    }
    return allZaps
  }

  const getZapFromWebhookId = async (zapId, webhookId) => {
    const nodes = await fetchZapNodes(zapId)
    const webhookZap = nodes.find((node) => {
      return node.code === webhookId
    })

    return webhookZap
  }

  const findWebhooks = (zap) => {
    const { nodes } = zap

    const webhookNodes = nodes.filter((node) => {
      return node.selected_api === 'WebHookAPI'
    })

    return webhookNodes.map((node) => {
      return {
        ...node,
        zapId: zap.id,
      }
    })
  }

  const getWebhooks = (zaps) => {
    const webhookZaps = []
    for (const zap of zaps) {
      webhookZaps.push(...findWebhooks(zap))
    }
    return webhookZaps
  }

  const parseWebhookUrl = (webhookUrl) => {
    const regex = /https:\/\/hooks\.zapier\.com\/hooks\/catch\/(\w+)\/(\w+)\/?/
    const matches = regex.exec(webhookUrl)
    const [, accountId, webhookId] = matches

    return {
      accountId,
      webhookId,
    }
  }

  const findZapForWebhookUrl = async (webhookUrl) => {
    const zaps = await getAllZaps()
    const webhookZaps = getWebhooks(zaps)
    const { webhookId } = parseWebhookUrl(webhookUrl)
    for (const webhookZap of webhookZaps) {
      const zap = await getZapFromWebhookId(webhookZap.zapId, webhookId)
      if (zap) {
        return zap
      }
    }
  }

  async function run(webhookUrl) {
    console.log('⌛ Looking for the zap that matches your webhook URL. Please wait...')
    const zap = await findZapForWebhookUrl(webhookUrl)

    if (!zap) {
      console.error('❌ Could not find the zap')
      return
    }

    console.log(`⚡ Found the zap:`, `https://zapier.com/app/editor/${zap.id}`)
  }

  // 👇 Paste your webhook URL here.
  run('https://hooks.zapier.com/hooks/catch/xxx/xxx/')
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment