Setting Up Automated Stock Alerts For Gardening Supplies
The basic architecture here is a web scraper that polls retailer product pages on a schedule, compares the current state against a stored state, and fires a Discord webhook when something changes. I built my first version using Python with requests and BeautifulSoup about two years ago. It tracked seed packets, soil amendments, and pruning tool replacements across four online nurseries. The setup itself takes roughly 30 minutes if you already have a Discord server and a home machine running continuously. Start by creating a Discord webhook. Go to your server settings, click Integrations, and create a new webhook. Copy the URL. You will need it shortly. The webhook endpoint accepts a simple POST request with a JSON body containing your message text. Discord rate limits webhooks to about five requests per second, which is plenty for stock notifications since they rarely come in bursts. For the scraping layer, I use a combination of scheduled checks and conditional logic rather than constant polling. Polling every minute destroys retailer servers and gets your IP blocked. Checking every six hours caught nearly everything I needed without triggering anti-bot measures. Some smaller nurseries update their inventory once daily, so hourly checks are pointless anyway.
Here is a minimal example of what the Python code looks like for a single product check: import requests import json import time WEBHOOK_URL = "YOUR_WEBHOOK_HERE" PRODUCT_URL = "https://example-nursery.com/product/organic-potting-mix" def check_stock(): r = requests.get(PRODUCT_URL, headers={"User-Agent": "Mozilla/5.0"}) in_stock = "out of stock" not in r.text.lower() return in_stock def notify(message): payload = {"content": message} requests.post(WEBHOOK_URL, json=payload) if __name__ == "__main__": while True: if check_stock(): notify("Stock alert: organic potting mix is back in stock") break time.sleep(21600) This runs, checks once, alerts you, and exits. A cron job or systemd timer handles repeated execution. On Linux I set mine to run at 6 AM and 6 PM daily. That covers the two restock windows most garden centers use.
The real complexity shows up when you scale past five products. I hit a wall around product twelve when the scrapers started returning inconsistent results. Different retailers structure their pages completely differently. One uses a simple "Add to Cart" button that disables when sold out. Another embeds stock level in a JavaScript variable that requires headless browser rendering. The third uses a completely different URL pattern for variants like bag size or plant height. For the JavaScript-heavy sites, I switched to Playwright instead of BeautifulSoup. It renders the full page before parsing, which costs more CPU and takes longer per check but catches stock states that static parsing misses entirely. The trade-off is worth it if you are tracking high-value items like rare orchid varieties or imported fertilizer blends that move fast. I also learned to cache the last known state locally and only send a notification when the state actually flips. Without this, a buggy page load that temporarily shows out of stock triggers a false alert. I added a two-check confirmation rule: the item must show as in stock on two consecutive checks thirty minutes apart before the webhook fires. This eliminated about forty percent of my false positives in the first month of operation.
Get the Full Details

Building A Product Watchlist
A single script is fine for one product. A watchlist requires a configuration file. I keep mine in YAML format with fields for product URL, name, last known stock status, variant options, and the check interval. Each product entry maps to a checker function. The checker function returns either True or False for in-stock, or None if the page could not be reached. None results skip notification logic entirely rather than triggering false alerts. The notification message itself should include enough context that you do not need to click through immediately. Retailer name, product name, price if available, and direct link. Discord supports embedded messages with color coding. I set green for in-stock alerts, red for backorder warnings, and gray for general status updates. This lets me scan a notification history in seconds and prioritize what to order first.
For the actual monitoring, I run everything through a systemd service with automatic restart on failure. If the Python process crashes, it comes back within sixty seconds. The service logs go to Journalctl, which makes debugging a bad fetch or a changed website layout much faster than checking scattered print statements.
Common Pitfalls And What I Wish I Knew Earlier
First, do not trust stock status shown on the initial page load alone. Many retailers show items as available during the page render and then remove them from the cart session on the server side when you actually try to check out. I lost several early orders this way. The workaround is to test add to cart through a headless browser rather than relying on a simple text scan. Yes, it is slower. Yes, it uses more resources. It also reduced my wasted notification clicks by about sixty percent. Second, consider geographic pricing and regional availability. A product might show in stock nationally but be unavailable in your shipping zone. I configured my checks to include zip code validation on the product page where possible. Most major retailers display regional availability on the product detail page if you look for it. Third, keep your User-Agent header rotating and realistic. I initially used a static header and got blocked by one nursery after two weeks. They implemented a simple bot detection rule. I switched to a small pool of five common browser User-Agents and rotate through them on each request. No sophisticated proxy infrastructure needed. Just basic rotation logic.

Limitations You Should Accept Upfront
This system will not replace every stocking decision you make. It misses physical store restocks. It misses flash sales that last under an hour. It cannot verify quality, compare specifications beyond what is listed on the product page, or negotiate bulk pricing. It is a notification tool, not a purchasing assistant. If you need real-time monitoring of sub-hour windows, you are better off using a dedicated stock-monitoring service like Keepa for Amazon products or Notibot for eBay listings. Those services already handle the edge cases around payment windows, cart expiration, and regional availability. My custom scraper works well for smaller nurseries and specialty suppliers that do not integrate with those platforms. There is also a maintenance cost. Retailers change their website layouts regularly. I have spent about three hours total over two years fixing broken parsers. Some months require zero maintenance. Others I spend a weekend rebuilding the entire script after a major site redesign. Factor that in before investing heavily in customization.
If you want a ready-made solution, there are several open-source stock notifier projects on GitHub that you can adapt. The most popular ones support Discord webhooks out of the box. Customizing them for gardening-specific retailers usually takes less time than building from scratch if you are comfortable with basic Python modification.