Fix timeout: strip HTML tags, bump Claude API timeout to 300s

Combined HTML from multiple sub-pages was too large. Now strips all HTML
tags and keeps only text content for Claude extraction. Also strips
nav/header/footer from sub-pages to remove duplication. Bumped Claude
API timeout from 120s to 300s. Updated wizard message to say 1-3 minutes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
John Mizerek 2026-03-14 13:53:31 -07:00
parent 37caa7c9bc
commit 5985a3732f
2 changed files with 24 additions and 16 deletions

View file

@ -2271,12 +2271,20 @@
<!--- Combine all page HTML into one text block ---> <!--- Combine all page HTML into one text block --->
<cfset combinedHtml = ""> <cfset combinedHtml = "">
<cfloop array="#menuPages#" index="menuPage"> <cfloop array="#menuPages#" index="menuPage">
<!--- Strip scripts, styles, and extract text content ---> <!--- Strip scripts, styles, comments, nav, header, footer --->
<cfset cleanHtml = menuPage.html> <cfset cleanHtml = menuPage.html>
<cfset cleanHtml = reReplaceNoCase(cleanHtml, "<script[^>]*>.*?</script>", "", "all")> <cfset cleanHtml = reReplaceNoCase(cleanHtml, "<script[^>]*>.*?</script>", "", "all")>
<cfset cleanHtml = reReplaceNoCase(cleanHtml, "<style[^>]*>.*?</style>", "", "all")> <cfset cleanHtml = reReplaceNoCase(cleanHtml, "<style[^>]*>.*?</style>", "", "all")>
<cfset cleanHtml = reReplaceNoCase(cleanHtml, "<!--.*?-->", "", "all")> <cfset cleanHtml = reReplaceNoCase(cleanHtml, "<!--.*?-->", "", "all")>
<cfset combinedHtml = combinedHtml & chr(10) & "--- PAGE: " & menuPage.url & " ---" & chr(10) & cleanHtml> <cfset cleanHtml = reReplaceNoCase(cleanHtml, "<nav[^>]*>.*?</nav>", "", "all")>
<cfset cleanHtml = reReplaceNoCase(cleanHtml, "<header[^>]*>.*?</header>", "", "all")>
<cfset cleanHtml = reReplaceNoCase(cleanHtml, "<footer[^>]*>.*?</footer>", "", "all")>
<!--- Strip all HTML tags, keep just text content for efficiency --->
<cfset cleanText = reReplaceNoCase(cleanHtml, "<[^>]+>", " ", "all")>
<!--- Collapse whitespace --->
<cfset cleanText = reReplace(cleanText, "\s{2,}", " ", "all")>
<cfset cleanText = trim(cleanText)>
<cfset combinedHtml = combinedHtml & chr(10) & "--- PAGE: " & menuPage.url & " ---" & chr(10) & cleanText>
</cfloop> </cfloop>
<!--- If we found embedded JSON, append it to help Claude find all menu items ---> <!--- If we found embedded JSON, append it to help Claude find all menu items --->
@ -2425,7 +2433,7 @@
<cfset arrayAppend(response.steps, "Sending to Claude API...")> <cfset arrayAppend(response.steps, "Sending to Claude API...")>
<!--- Call Claude API ---> <!--- Call Claude API --->
<cfhttp url="https://api.anthropic.com/v1/messages" method="POST" timeout="120" result="httpResult"> <cfhttp url="https://api.anthropic.com/v1/messages" method="POST" timeout="300" result="httpResult">
<cfhttpparam type="header" name="Content-Type" value="application/json"> <cfhttpparam type="header" name="Content-Type" value="application/json">
<cfhttpparam type="header" name="x-api-key" value="#CLAUDE_API_KEY#"> <cfhttpparam type="header" name="x-api-key" value="#CLAUDE_API_KEY#">
<cfhttpparam type="header" name="anthropic-version" value="2023-06-01"> <cfhttpparam type="header" name="anthropic-version" value="2023-06-01">

View file

@ -1397,11 +1397,11 @@
<div class="loading-spinner"></div> <div class="loading-spinner"></div>
<span>Crawling website and extracting menu data...</span> <span>Crawling website and extracting menu data...</span>
</div> </div>
<p style="font-size:13px;color:var(--gray-500);margin-top:8px;">This may take 30-60 seconds while I fetch pages, download images, and analyze everything.</p> <p style="font-size:13px;color:var(--gray-500);margin-top:8px;">This may take 1-3 minutes while I crawl menu pages, grab photos from ordering platforms, and analyze everything.</p>
`); `);
try { try {
const response = await fetch(`${config.apiBaseUrl}/setup/analyzeMenuUrl.cfm`, { const response = await fetch(`${config.apiBaseUrl}/setup/analyzeMenuUrl.php`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url }) body: JSON.stringify({ url })
@ -1493,8 +1493,8 @@
const formData = new FormData(); const formData = new FormData();
formData.append('zipFile', file); formData.append('zipFile', file);
console.log('Uploading ZIP to:', `${config.apiBaseUrl}/setup/uploadSavedPage.cfm`); console.log('Uploading ZIP to:', `${config.apiBaseUrl}/setup/uploadSavedPage.php`);
const uploadResponse = await fetch(`${config.apiBaseUrl}/setup/uploadSavedPage.cfm`, { const uploadResponse = await fetch(`${config.apiBaseUrl}/setup/uploadSavedPage.php`, {
method: 'POST', method: 'POST',
body: formData body: formData
}); });
@ -1533,7 +1533,7 @@
`); `);
// Now analyze the extracted URL with Playwright // Now analyze the extracted URL with Playwright
const response = await fetch(`${config.apiBaseUrl}/setup/analyzeMenuUrl.cfm`, { const response = await fetch(`${config.apiBaseUrl}/setup/analyzeMenuUrl.php`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url: uploadResult.URL }) body: JSON.stringify({ url: uploadResult.URL })
@ -1549,7 +1549,7 @@
const htmlContent = await file.text(); const htmlContent = await file.text();
console.log('Sending HTML content, length:', htmlContent.length); console.log('Sending HTML content, length:', htmlContent.length);
const response = await fetch(`${config.apiBaseUrl}/setup/analyzeMenuUrl.cfm`, { const response = await fetch(`${config.apiBaseUrl}/setup/analyzeMenuUrl.php`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ html: htmlContent }) body: JSON.stringify({ html: htmlContent })
@ -1813,7 +1813,7 @@
}); });
formData.append('businessId', config.businessId); formData.append('businessId', config.businessId);
const response = await fetch(`${config.apiBaseUrl}/setup/analyzeMenuImages.cfm`, { const response = await fetch(`${config.apiBaseUrl}/setup/analyzeMenuImages.php`, {
method: 'POST', method: 'POST',
body: formData body: formData
}); });
@ -2000,7 +2000,7 @@
// Check for duplicate businesses before creating a new one // Check for duplicate businesses before creating a new one
async function checkForDuplicateBusiness(biz) { async function checkForDuplicateBusiness(biz) {
try { try {
const response = await fetch(`${config.apiBaseUrl}/setup/checkDuplicate.cfm`, { const response = await fetch(`${config.apiBaseUrl}/setup/checkDuplicate.php`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
@ -2271,7 +2271,7 @@
if (!taxInput) return; if (!taxInput) return;
try { try {
const resp = await fetch(`/api/setup/lookupTaxRate.cfm?zip=${encodeURIComponent(zipCode)}`); const resp = await fetch(`/api/setup/lookupTaxRate.php?zip=${encodeURIComponent(zipCode)}`);
const data = await resp.json(); const data = await resp.json();
if (data.OK && data.taxRate > 0) { if (data.OK && data.taxRate > 0) {
@ -3182,7 +3182,7 @@
saveBtn.disabled = true; saveBtn.disabled = true;
try { try {
const response = await fetch(`${config.apiBaseUrl}/setup/saveWizard.cfm`, { const response = await fetch(`${config.apiBaseUrl}/setup/saveWizard.php`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@ -3243,7 +3243,7 @@
formData.append('BusinessID', finalBusinessId); formData.append('BusinessID', finalBusinessId);
formData.append('header', config.headerImageFile); formData.append('header', config.headerImageFile);
const headerResp = await fetch(`${config.apiBaseUrl}/menu/uploadHeader.cfm`, { const headerResp = await fetch(`${config.apiBaseUrl}/menu/uploadHeader.php`, {
method: 'POST', method: 'POST',
body: formData body: formData
}); });
@ -3292,7 +3292,7 @@
formData.append('ItemID', dbItemId); formData.append('ItemID', dbItemId);
formData.append('photo', file); formData.append('photo', file);
const imgResp = await fetch(`${config.apiBaseUrl}/menu/uploadItemPhoto.cfm`, { const imgResp = await fetch(`${config.apiBaseUrl}/menu/uploadItemPhoto.php`, {
method: 'POST', method: 'POST',
body: formData body: formData
}); });
@ -3512,7 +3512,7 @@
async function loadBusinessInfo() { async function loadBusinessInfo() {
try { try {
const response = await fetch(`${config.apiBaseUrl}/businesses/get.cfm`, { const response = await fetch(`${config.apiBaseUrl}/businesses/get.php`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ BusinessID: config.businessId }) body: JSON.stringify({ BusinessID: config.businessId })