AutoDrop — One-click Product • Reel • Page
AutoDrop — find → page → reel → publish

1) Find winning products

Rainforest API

Search Amazon via your secure worker. We score demand, competition, margin, and seasonality into a WinScore.

2) Generate product page

A11y • SEO • JSON-LD

Preview a lean, fast product page. Download a single HTML file and deploy anywhere.

Try .99 endings and A/B test nearby price points.

3) Craft Reel script & caption

Short-form best practices

Create a native-feeling plan: hook, beats, caption, hashtags. Upload a video or publish an image post.

No video? We can publish an image post from the product image.

4) Growth & extras

A/B • Email • UTM • Policies

A/B copy (hero)

Enter two headlines; rotate & log locally.

Email capture embed

Paste into the exported page.

UTM builder

Policies

Generate Terms/Privacy/Returns stubs.

© AutoDrop • Built for you

${esc(p.title)}

${esc(p.subtitle)}

Limited stock — today’s price secured at checkout.
${priceTag}
Buy now
${(p.badges||[]).map(b=>`${esc(b)}`).join("")}
    ${features}

${esc(p.shipping_note)} • ${esc(p.guarantee)}

Details

SKU${esc(p.sku)}

FAQ

${faqs}
`; } // ---------- REELS ---------- $("btnBuildReel").addEventListener("click", ()=>{ if(!state.selected){ toast("Pick a product first",false); return } const tone = $("tone").value; const bullets = (state.selected.bullets||[]).slice(0,3); const hook = chooseHook(state.selected,tone); const beats = [ `Hook: ${hook}`, "Show the core benefit in 3 seconds", "Demonstrate a before/after use case", "Overlay 2–3 micro-features with text", "CTA: Tap link in bio" ]; const script = beats.map((b,i)=>`[0:${String(i*3).padStart(2,'0')}] ${b}`).join("\n"); const tags = buildHashtags(state.selected); const caption = `${hook}\n\nWhy it slaps:\n• ${bullets[0]||"Instant upgrade"}\n• ${bullets[1]||"Easy to use"}\n• ${bullets[2]||"Built to last"}\n\nTap the link in bio to get yours.\n\n${tags.join(" ")}`; $("scriptOut").value=script; $("hashtagsOut").value=tags.join(" "); $("captionOut").value=caption; $("charCount").textContent = caption.length + " / 2200"; state.reelPlan = { script, caption, tags }; setStatus("Reel plan generated"); toast("Reel plan ready"); }); function chooseHook(p,t){ const t4=(p.title||"").split(" ").slice(0,4).join(" "); const v=[`Stop scrolling — this ${t4} changes everything.`,`${t4} you’ll actually use daily.`,`POV: you just saved $20 with this ${t4}.`,`Why everyone’s grabbing this ${t4}.`]; return v[Math.floor(Math.random()*v.length)]; } function buildHashtags(p){ const base=["#onlineshopping","#dailyfinds","#musthave","#viralproducts","#useful"]; const cat=(p.category||"").toLowerCase(); const niche = cat.includes("pet")?["#petproducts","#dogsoftiktok","#petparent"] :cat.includes("kitchen")?["#kitchenfinds","#homecafe","#coffeelover"] :["#giftideas","#amazonfinds","#homefinds"]; return [...niche,...base].slice(0,12); } // ---------- INSTAGRAM ---------- $("btnConnectIg").addEventListener("click",()=>{ location.href="/api/instagram/start" }); $("btnPublishIg").addEventListener("click", async ()=>{ if(!state.selected||!state.reelPlan){ toast("Pick product + build reel plan first",false); return } $("igStatus").textContent="Publishing…"; startBar(); try{ let uploadUrl=null; const file=$("reelFile").files[0]; if(file){ const fd=new FormData(); fd.append("file",file); const up=await fetch("/api/upload",{method:"POST",body:fd}); if(!up.ok) throw new Error("Upload failed"); uploadUrl=(await up.json()).url; } const resp=await fetch("/api/instagram/publish",{method:"POST",headers:{"Content-Type":"application/json"}, body:JSON.stringify({caption:$("captionOut").value,product_image:state.selected.image,media_type:file?"REELS":"IMAGE",video_url:uploadUrl})}); const j=await resp.json(); if(!resp.ok) throw new Error(j.error||"Publish failed"); $("igStatus").textContent="Published! Media ID: "+j.media_id; toast("Instagram published"); setStatus("Instagram published"); }catch(e){ console.error(e); $("igStatus").textContent="Error: "+e.message; toast(e.message,false) } finally{ endBar(); resetBar() } }); // ---------- STRIPE ---------- $("btnStripe").addEventListener("click", async ()=>{ try{ if(!state.selected){ toast("Pick a product first",false); return } const cents = Math.round(Number($("price").value || state.selected.price || 0)*100); if(!cents || cents<100){ toast("Set a valid price first",false); return } const r=await fetch("/api/stripe/create_payment_link",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:state.selected.title||"AutoDrop Product",price_cents:cents})}); const j=await r.json(); if(!r.ok) throw new Error(j.error||"Stripe error"); $("checkoutUrl").value=j.url; $("stripeConn").textContent="Payment Link ready"; state.stripeConnected=true; toast("Stripe link created"); }catch(e){ toast(e.message,false) } }); // ---------- GROWTH ---------- $("btnStartAB").addEventListener("click",()=>{ state.abRunning=true; toast("A/B started — rotate your hero in the export") }); $("btnUtm").addEventListener("click",()=>{ const u=buildUtmFromInputs($("checkoutUrl").value||""); $("utmOut").textContent=u; state.utm=u; }); $("btnPolicies").addEventListener("click",()=>{ alert("We’ll append Terms/Privacy/Returns placeholders to your export. Customize for your locale.") }); $("btnCopyEmbed").addEventListener("click",()=>{ navigator.clipboard.writeText($("embedOut").value).then(()=>toast("Embed copied")) }); function seedEmbed(){ $("embedOut").value = `
`; } function buildUtmFromInputs(base){ try{ const u=new URL(base||"#"); const s=$("utmSource").value||"instagram", m=$("utmMedium").value||"social", c=$("utmCampaign").value||"launch"; if(base){ u.searchParams.set("utm_source",s); u.searchParams.set("utm_medium",m); u.searchParams.set("utm_campaign",c) } return base?u.toString():base; }catch{ return base } } function slugify(s){return (s||"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/(^-|-$)/g,"")} ``` if you want me to tweak the palette to your brand, say your primary/secondary colors and i’ll swap variables (keeping contrast ≥ WCAG AA so you never get unreadable text).