| name | zepto |
| description | Complete Zepto automation - authentication, address setup, shopping, personalized recommendations based on order history, and payment link generation. Triggers on zepto, grocery, quick commerce, add to cart, milk, bread, butter, vegetables. |
| metadata | {"openclaw":{"emoji":"๐","requires":{"config":["browser.enabled"]}}} |
Zepto India Grocery Skill
Complete end-to-end Zepto automation: authenticate user, confirm delivery address, shop for groceries with personalized recommendations, and generate Juspay payment links.
Complete Flow
- Authentication - Phone + OTP verification
- Address Confirmation - Verify delivery location
- Shopping - Search & add items (with YOUR usuals prioritized!)
- Payment Link - Generate & send Juspay link via WhatsApp
Step 0: Order History & Usuals
Your order history is tracked in: {SKILL_DIR}/order-history.json
(Where {SKILL_DIR} is your skill directory, typically ~/.openclaw/skills/zepto/)
Smart Selection Logic:
- When user requests an item (e.g., "add milk")
- Check
order-history.json for that category
- If ordered 2+ times โ Auto-add your most-ordered variant
- If ordered 0-1 times โ Show options and ask for selection
Automated Order History Scraper
When to run: User says "update my zepto history" or "refresh order history"
Process:
- Navigate to account page
- Get all delivered order URLs
- Visit each order sequentially
- Extract items using DOM scraping
- Build frequency map
- Save to
order-history.json
Implementation:
browser navigate url=https://www.zepto.com/account profile=openclaw
browser act profile=openclaw request='{"fn":"() => { const orders = []; document.querySelectorAll(\"a[href*=\\\"/order/\\\"]\").forEach(link => { if (link.href.includes(\"isArchived=false\") && link.textContent.includes(\"delivered\")) { orders.push(link.href); } }); return [...new Set(orders)]; }", "kind":"evaluate"}'
browser navigate url={order_url} profile=openclaw
browser act profile=openclaw request='{"fn":"() => { const items = []; document.querySelectorAll(\"*\").forEach(el => { const text = el.textContent; if (text.match(/\\d+\\s*unit/i)) { const parent = el.closest(\"div\"); if (parent) { const lines = parent.textContent.split(\"\\n\").map(l => l.trim()).filter(l => l && l.length > 5 && l.length < 100); if (lines[0]) { const qtyMatch = text.match(/(\\d+)\\s*unit/i); items.push({ name: lines[0], quantity: qtyMatch ? parseInt(qtyMatch[1]) : 1 }); } } } }); const uniqueItems = {}; items.forEach(item => { if (!uniqueItems[item.name]) uniqueItems[item.name] = item; }); return Object.values(uniqueItems); }", "kind":"evaluate"}'
write path={SKILL_DIR}/order-history.json content={json_data}
Automated scraper advantages:
- โ
No manual screenshot review
- โ
Faster (visits all orders programmatically)
- โ
Always up-to-date
- โ
Can re-run anytime
Example:
User: "Update my Zepto order history"
Response:
"๐ Scanning your Zepto orders...
๐ฆ Found 6 delivered orders
๐ Extracting items...
โ
Updated! Found:
- Coriander: 4 orders
- Milk: 3 orders
- Bread: 2 orders
- Potato: 2 orders
+ 15 other items
Your usuals are ready!"
Smart Selection Logic (Using History):
Example:
User: "Add milk"
[Check order-history.json]
โ "Amul Taaza Toned Fresh Milk | Pouch (500ml)" ordered 3x
Response:
"๐ฅ Adding your usual milk!
Amul Taaza Toned Fresh Milk (500ml) - โน29
๐ You've ordered this 3 times
โ
Added to cart"
If only ordered once or never:
User: "Add milk"
[Check order-history.json]
โ "Amul Taaza" ordered 1x only
Response:
"๐ฅ Found some milk options:
1. Amul Taaza Toned (500ml) - โน29 โญ 4.8 (100k) - You've ordered this once
2. Amul Gold (1L) - โน68 โญ 4.9 (80k) - Most popular
3. Mother Dairy (500ml) - โน30 โญ 4.7 (60k)
Which one? (or tell me a number)"
Update order history: After each successful order, update the JSON file with new items.
Step 1: Authentication (First Time Only)
Check if already logged in:
browser open url=https://www.zepto.com profile=openclaw
browser snapshot --interactive profile=openclaw
If NOT logged in, start auth flow:
1.1: Get Phone Number
Ask user: "What's your phone number for Zepto? (10 digits)"
1.2: Enter Phone & Request OTP
browser act profile=openclaw request='{"kind":"click","ref":"{login_button_ref}"}'
browser act profile=openclaw request='{"kind":"type","ref":"{phone_input_ref}","text":"{phone}"}'
browser act profile=openclaw request='{"kind":"click","ref":"{continue_button_ref}"}'
1.3: Get OTP from User
Ask user: "I've sent the OTP to {phone}. What's the OTP you received?"
1.4: Enter OTP
browser snapshot --interactive profile=openclaw
browser act profile=openclaw request='{"kind":"type","ref":"{otp_input_ref}","text":"{otp}"}'
Result: User is now logged in! Session persists across browser restarts.
Step 2: Address Confirmation
Open location selector:
browser act profile=openclaw request='{"kind":"click","ref":"{select_location_button_ref}"}'
browser screenshot profile=openclaw
Ask user to confirm:
Your saved addresses:
1. Home - 123 Main Street, Mumbai
2. Office - 456 Park Avenue, Delhi
Which address for delivery? (Reply with number or name)
Select address (CRITICAL TECHNIQUE):
The address name itself is clickable in the modal! Use JavaScript to find and click it:
browser act profile=openclaw request='{"fn":"() => { const headings = document.querySelectorAll(\"h1, h2, h3, h4, h5, h6, p, span, div\"); for (let h of headings) { if (h.textContent.trim() === \"{USER_ADDRESS_NAME}\" && h.offsetParent !== null) { h.click(); return \"clicked: \" + h.tagName; } } return \"not found\"; }","kind":"evaluate"}'
KEY INSIGHT: The address name (e.g., "Home", "Office") shows a hand cursor on hover and is directly clickable. Don't try to click containers or buttons around it - click the text element itself.
Confirm serviceability:
browser navigate url=https://www.zepto.com profile=openclaw
Report to user:
โ
Delivery address: {address_name}
๐ {full_address}
โฑ๏ธ ETA: {eta} mins
๐ช Store: {store_name}
Ready to shop! What would you like to add to cart?
Step 3: Shopping
3A: Discovery Mode (Browse & Explore)
When user asks to "explore", "show me", "what's good", "find something", or "discover":
Common Discovery Patterns:
- "Show me healthy snacks under โน50"
- "What's good in dairy products?"
- "Find me something for breakfast"
- "Any deals on fruits?"
- "Discover protein bars"
Browse Categories:
browser navigate url=https://www.zepto.com profile=openclaw
browser snapshot --interactive profile=openclaw
Filter & Sort:
browser navigate url=https://www.zepto.com/pn/munchies profile=openclaw
browser snapshot --interactive profile=openclaw
browser screenshot profile=openclaw
Discovery Response Format:
๐ Found some great options in {category}:
1. **{Product Name}** - โน{price} ({discount}% OFF)
โญ {rating} ({review_count} reviews)
๐ฆ {size/quantity}
2. **{Product Name}** - โน{price}
โญ {rating} ({review_count} reviews)
3. **{Product Name}** - โน{price} ({discount}% OFF)
โญ {rating} ({review_count} reviews)
Want me to add any of these? Just tell me the number(s)!
Smart Filtering Tips:
- Price range: Extract from query ("under โน50", "below 100")
- Discount focus: Look for items with โนX OFF tags
- High ratings: Prioritize 4.5+ star products
- Popular items: Sort by review count (k = thousands)
- Health focus: Keywords like "protein", "sugar-free", "organic", "millet"
Interactive Discovery:
After showing options, user can:
- Add by number: "Add 1 and 3"
- Ask for more: "Show me more"
- Refine: "Show cheaper options" or "What about chocolate flavors?"
- Browse different category: "Now show me dairy products"
3B: Direct Search (Specific Items)
When user names a specific item:
browser navigate url=https://www.zepto.com/search?query={item} profile=openclaw
browser snapshot --interactive profile=openclaw
Select Best Product
Rule: Pick product with highest review count.
Format: {rating} ({count}) where k=thousand, M=million.
Example: "4.8 (694.4k)" = 694,400 reviews = most popular.
Add to Cart
browser act profile=openclaw request='{"kind":"click","ref":"{ADD_button_ref}"}'
Multi-Item Flow
For "add milk, butter, bread":
- Search milk โ pick best โ ADD
- Search butter โ pick best โ ADD
- Search bread โ pick best โ ADD
- View cart summary
CRITICAL - Quantity Mapping:
When user provides a shopping list with quantities (e.g., "3x jeera, 2x saffola oats"):
- ALWAYS create a mapping file FIRST before any cart operations
- Map each item name to its requested quantity
- Before removing/modifying items, verify against this mapping
- Never assume which item has which quantity - CHECK THE MAPPING
Example mapping:
{
"jeera": 3,
"saffola_oats": 2,
"milk": 1
}
Before removing duplicates or adjusting quantities:
- Take a cart snapshot
- Match cart items to your mapping by name similarity
- Verify quantities match the original request
- If unsure, ASK the user before making changes
View Cart
browser navigate url=https://www.zepto.com/?cart=open profile=openclaw
browser snapshot profile=openclaw
Step 4: Generate Payment Link
After all items added to cart:
4.1: Proceed to Payment
browser act profile=openclaw request='{"kind":"click","ref":"{proceed_to_payment_button_ref}"}'
4.2: Extract Juspay Link
URL Format:
https://payments.juspay.in/payment-page/signature/zeptomarketplace-{order_id}
Example:
https://payments.juspay.in/payment-page/signature/zeptomarketplace-019c2a455a630000000000009e6f261c
4.3: Send Link via WhatsApp
message action=send channel=whatsapp target={user_phone} message="๐ Your Zepto order is ready!
{cart_summary}
๐ฐ Total: โน{total}
๐ Click here to pay:
{juspay_payment_link}
After payment, your order will be confirmed automatically! ๐"
Payment Link Features:
- โ
Shareable across devices
- โ
Works on mobile browser
- โ
Redirects to Zepto after payment
- โ
Order confirmed automatically
- โ
Secure (Juspay gateway)
Response Format
After successful cart + payment link generation:
๐ Added to Zepto cart:
- Amul Gold Milk (1L) - โน68 (4.8โ
, 100k reviews)
- Amul Butter (100g) - โน58 (4.9โ
, 50k reviews)
- Britannia Bread (400g) - โน42 (4.7โ
, 80k reviews)
๐ฐ Total: โน168
๐ Payment link sent to your WhatsApp!
Click the link to pay and confirm your order. Delivery in ~15 mins! ๐
Safety & Best Practices
โ
DO:
- Check auth status before every order
- Confirm address with user
- Extract payment link accurately
- Send link via WhatsApp
- Let user complete payment
โ DON'T:
- Never click "Pay" button
- Never store OTP
- Never auto-submit payment
- Never change address without user confirmation
Error Handling
Phone number invalid:
"Phone number should be 10 digits. Please try again."
OTP verification failed:
"OTP verification failed. Let me resend the OTP.
Check your phone for the new code."
Location not serviceable:
"โ ๏ธ Your location is currently not serviceable by Zepto.
Store might be temporarily closed or location outside delivery zone.
Want to try a different address?"
Item not found:
"Couldn't find {item} on Zepto. Try a different search term?"
Session Persistence
After successful authentication:
- Browser cookies persist login
- No need to re-authenticate for future orders
- Address selection persists
- Can directly proceed to shopping
To check if authenticated:
browser navigate url=https://www.zepto.com profile=openclaw
browser snapshot --interactive profile=openclaw