Created
August 28, 2024 21:03
-
-
Save marcosoliveeira1/c6af7a103a166cdfa611ebdd8d4a770a to your computer and use it in GitHub Desktop.
Find Zap by Webhook URL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Run this code in browser console | |
## Based on https://gist.github.com/ikbelkirasan/601dd8a51f458bf09d5ce44a102b9fd0 | |
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 (zap, webhookId) => { | |
try { | |
const response = await fetch(`https://zapier.com/api/gulliver/steptesting/v1/zaps/${zap.id}/subscriptions?account_id=${zap.accountId}`); | |
const { subscriptions } = await response.json(); | |
const webhookZap = subscriptions.find(obj => { | |
return obj?.hook_url.includes(webhookId); | |
}); | |
return webhookZap ? zap : null; | |
} catch (error) { | |
return null; | |
} | |
}; | |
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, | |
accountId: zap.account_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 fetchWebhookZaps = async (webhookZaps, webhookId, concurrency = 20) => { | |
const getZapFromWebhookId = async (zap, webhookId) => { | |
try { | |
const response = await fetch(`https://zapier.com/api/gulliver/steptesting/v1/zaps/${zap.id}/subscriptions?account_id=${zap.accountId}`); | |
const { subscriptions } = await response.json(); | |
const webhookZap = subscriptions.find(obj => obj?.hook_url.includes(webhookId)); | |
return webhookZap ? zap : null; | |
} catch (error) { | |
return null; | |
} | |
}; | |
const fetchBatch = async (batch) => { | |
const results = await Promise.all(batch.map(webhookZap => getZapFromWebhookId(webhookZap, webhookId))); | |
return results.filter(result => result !== null); | |
}; | |
const batches = []; | |
for (let i = 0; i < webhookZaps.length; i += concurrency) { | |
const batch = webhookZaps.slice(i, i + concurrency); | |
batches.push(fetchBatch(batch)); | |
} | |
const results = await Promise.all(batches); | |
return results.flat(); | |
}; | |
const findZapForWebhookUrl = async webhookUrl => { | |
const zaps = await getAllZaps(); | |
console.log("π Found", zaps.length, "zaps."); | |
const webhookZaps = getWebhooks(zaps); | |
console.log("π Found", webhookZaps.length, "webhooks."); | |
const { webhookId } = parseWebhookUrl(webhookUrl); | |
const foundZaps = await fetchWebhookZaps(webhookZaps, webhookId); | |
if (foundZaps.length > 0) { | |
console.log("π Found the zap:", foundZaps); | |
return foundZaps; | |
} | |
}; | |
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[0].zapId}`); | |
} | |
// π Paste your webhook URL here. | |
run("https://hooks.zapier.com/hooks/catch/XXXXX/XXXXXX"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment