Overview
Searches Walmart daily for tracked products, records availability and price, and alerts when a product goes out of stock or changes price by more than a configurable threshold.
Trigger
Daily cron at 9 AM
Schedule
Daily at 9 AM (cron: 0 9 * * *)
Workflow Steps
Load tracked Walmart products
Read product search queries from a walmart_products table with fields: product_name, last_price, last_available.
Search Walmart for each product
POST to Scavio search API with platform: walmart for each product. Extract top result: title, price, availability status.
Detect availability changes
Compare current availability against last_available in database. Flag if changed from in-stock to out-of-stock or vice versa.
Detect price changes
Compare current price against last_price. Calculate change percentage. Flag if absolute change exceeds 5%.
Store daily snapshot
Insert product_name, price, is_available, date into walmart_snapshots table. Update walmart_products with latest values.
Send alerts
For stockouts or price changes above threshold, send Slack/webhook alert with product name, change type, old and new values, and Walmart URL.
Python Implementation
import sqlite3
import requests
from datetime import date
import re
import time
DB_PATH = "walmart_monitor.db"
SCRAVIO_KEY = "YOUR_API_KEY"
PRICE_CHANGE_THRESHOLD = 0.05
ALERT_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK"
def init_db():
conn = sqlite3.connect(DB_PATH)
conn.executescript("""
CREATE TABLE IF NOT EXISTS walmart_products (
id INTEGER PRIMARY KEY, product_name TEXT, last_price REAL,
last_available INTEGER DEFAULT 1, last_checked TEXT
);
CREATE TABLE IF NOT EXISTS walmart_snapshots (
product_name TEXT, price REAL, is_available INTEGER, url TEXT, date TEXT
);
""")
conn.commit()
return conn
def parse_price(s: str) -> float | None:
if not s:
return None
m = re.search(r'[\d]+\.?\d*', s.replace(',', ''))
return float(m.group()) if m else None
def search_walmart(query: str) -> dict | None:
resp = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": SCRAVIO_KEY},
json={"query": query, "platform": "walmart", "num": 3}
)
resp.raise_for_status()
results = resp.json().get("results", [])
if not results:
return None
r = results[0]
price = parse_price(r.get("price", ""))
in_stock = "out of stock" not in (r.get("snippet", "") + r.get("availability", "")).lower()
return {"price": price, "is_available": in_stock, "url": r.get("url", ""), "title": r.get("title", "")}
def run():
conn = init_db()
today = date.today().isoformat()
products = conn.execute("SELECT id, product_name, last_price, last_available FROM walmart_products").fetchall()
for pid, name, last_price, last_available in products:
result = search_walmart(name)
if not result:
time.sleep(0.5)
continue
new_price = result["price"]
new_avail = int(result["is_available"])
alerts = []
if last_available and not new_avail:
alerts.append(f"{name} went OUT OF STOCK on Walmart")
elif not last_available and new_avail:
alerts.append(f"{name} is back IN STOCK on Walmart")
if new_price and last_price and last_price > 0:
change = abs(new_price - last_price) / last_price
if change >= PRICE_CHANGE_THRESHOLD:
direction = "up" if new_price > last_price else "down"
alerts.append(f"{name} price went {direction}: ${last_price:.2f} -> ${new_price:.2f} ({change*100:.1f}%)")
for alert in alerts:
requests.post(ALERT_WEBHOOK, json={"text": f"Walmart alert: {alert} {result['url']}"})
conn.execute("INSERT INTO walmart_snapshots VALUES (?,?,?,?,?)", (name, new_price, new_avail, result["url"], today))
conn.execute("UPDATE walmart_products SET last_price=?, last_available=?, last_checked=? WHERE id=?", (new_price, new_avail, today, pid))
conn.commit()
time.sleep(0.5)
if __name__ == "__main__":
run()
JavaScript Implementation
const Database = require('better-sqlite3');
const fetch = require('node-fetch');
const DB_PATH = 'walmart_monitor.db';
const SCRAVIO_KEY = 'YOUR_API_KEY';
const THRESHOLD = 0.05;
const ALERT_WEBHOOK = 'https://hooks.slack.com/services/YOUR/WEBHOOK';
const db = new Database(DB_PATH);
db.exec(`
CREATE TABLE IF NOT EXISTS walmart_products (id INTEGER PRIMARY KEY, product_name TEXT, last_price REAL, last_available INTEGER DEFAULT 1, last_checked TEXT);
CREATE TABLE IF NOT EXISTS walmart_snapshots (product_name TEXT, price REAL, is_available INTEGER, url TEXT, date TEXT);
`);
function parsePrice(s) { const m = (s||'').replace(/,/g,'').match(/[\d]+\.?\d*/); return m ? parseFloat(m[0]) : null; }
async function searchWalmart(query) {
const res = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: { 'x-api-key': SCRAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, platform: 'walmart', num: 3 })
});
const results = (await res.json()).results || [];
if (!results.length) return null;
const r = results[0];
return { price: parsePrice(r.price), is_available: !(r.snippet||'').toLowerCase().includes('out of stock'), url: r.url };
}
async function run() {
const today = new Date().toISOString().slice(0, 10);
const products = db.prepare('SELECT id, product_name, last_price, last_available FROM walmart_products').all();
for (const { id, product_name, last_price, last_available } of products) {
const result = await searchWalmart(product_name);
if (!result) { await new Promise(r => setTimeout(r, 500)); continue; }
const { price, is_available, url } = result;
const alerts = [];
if (last_available && !is_available) alerts.push(`${product_name} OUT OF STOCK`);
else if (!last_available && is_available) alerts.push(`${product_name} back IN STOCK`);
if (price && last_price && Math.abs(price - last_price) / last_price >= THRESHOLD)
alerts.push(`${product_name} price: $${last_price} -> $${price}`);
for (const a of alerts) await fetch(ALERT_WEBHOOK, { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ text: `Walmart: ${a} ${url}` }) });
db.prepare('INSERT INTO walmart_snapshots VALUES (?,?,?,?,?)').run(product_name, price, is_available?1:0, url, today);
db.prepare('UPDATE walmart_products SET last_price=?, last_available=?, last_checked=? WHERE id=?').run(price, is_available?1:0, today, id);
await new Promise(r => setTimeout(r, 500));
}
}
run().catch(console.error);
Platforms Used
Walmart
Product search with pricing and fulfillment data