Tutorial2 min readUpdated Mar 22, 2026

Build a Deal Finder Bot with PriceFetch

TL;DR

Monitor prices with PriceFetch API, detect deals based on configurable thresholds, and post them to Telegram or Discord channels automatically.

What the Bot Does

The deal finder bot watches a list of products and posts to a channel when it finds a price that's significantly below the product's historical average or a preset threshold. Think of it as an automated version of deal forums like Slickdeals, but customized to the products you care about.

The bot runs as a cron job — it checks prices, evaluates deals, and posts if something qualifies. No long-running process needed. We'll build for both Telegram and Discord so you can pick your platform.

Try it yourself — 500 free API credits, no credit card required.

Start Free

Telegram Bot Setup

Create a Telegram bot through BotFather and get your bot token. Then create a channel and add the bot as an administrator so it can post messages.

1. Message @BotFather on Telegram 2. Send `/newbot` and follow the prompts 3. Save the bot token 4. Create a channel, add the bot as admin 5. Get the channel ID (send a message in the channel, then check `https://api.telegram.org/bot<TOKEN>/getUpdates`)

bash
pip install httpx python-telegram-bot

# Store your tokens
export PRICEFETCH_API_KEY="pf_your_key_here"
export TELEGRAM_BOT_TOKEN="1234567890:ABCdef..."
export TELEGRAM_CHANNEL_ID="-1001234567890"

Deal Detection Logic

A "deal" means different things in different contexts. We use two strategies: absolute threshold (price below a set amount) and percentage drop (price is X% below the product's recent average). You configure both per product.

The deal checker fetches the current price, compares it against your criteria, and returns whether it qualifies as a deal worth posting.

python
import httpx
import json
import os
from dataclasses import dataclass
from pathlib import Path

API_KEY = os.environ["PRICEFETCH_API_KEY"]

@dataclass
class Deal:
    name: str
    url: str
    current_price: float
    currency: str
    threshold: float
    savings_pct: float

def check_for_deals(watchlist_file: str = "watchlist.json") -> list[Deal]:
    """Check all watched products for deals."""
    watchlist = json.loads(Path(watchlist_file).read_text())
    deals: list[Deal] = []

    for item in watchlist:
        resp = httpx.get(
            "https://api.pricefetch.dev/v1/price",
            params={"url": item["url"]},
            headers={"X-API-Key": API_KEY},
            timeout=15.0,
        )
        data = resp.json()
        if not data["success"] or not data["data"]["in_stock"]:
            continue

        price = data["data"]["price"]
        currency = data["data"]["currency"]
        threshold = item.get("target_price", float("inf"))

        if price <= threshold:
            savings = ((threshold - price) / threshold) * 100
            deals.append(Deal(
                name=item["name"], url=item["url"],
                current_price=price, currency=currency,
                threshold=threshold, savings_pct=round(savings, 1),
            ))

    return deals

Posting Deals to Telegram

The Telegram integration sends a formatted message for each deal found. We use Markdown formatting for a clean look in the channel. Each message includes the product name, current price, savings percentage, and a direct link.

python
import asyncio
from telegram import Bot

TELEGRAM_TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]
CHANNEL_ID = os.environ["TELEGRAM_CHANNEL_ID"]

async def post_to_telegram(deals: list[Deal]) -> None:
    """Post deals to a Telegram channel."""
    bot = Bot(token=TELEGRAM_TOKEN)
    for deal in deals:
        message = (
            f"*Deal Found!*\n\n"
            f"*{deal.name}*\n"
            f"Price: *{deal.currency} {deal.current_price:.2f}*\n"
            f"Target: {deal.currency} {deal.threshold:.2f}\n"
            f"Savings: {deal.savings_pct}% off\n\n"
            f"[View Product]({deal.url})"
        )
        await bot.send_message(
            chat_id=CHANNEL_ID,
            text=message,
            parse_mode="Markdown",
            disable_web_page_preview=False,
        )

# Main entry point
def run_deal_finder():
    deals = check_for_deals()
    if deals:
        print(f"Found {len(deals)} deals!")
        asyncio.run(post_to_telegram(deals))
    else:
        print("No deals found.")

if __name__ == "__main__":
    run_deal_finder()

Discord Webhook Alternative

If you prefer Discord, you can use webhooks instead of a full bot. Webhooks are simpler — no bot token needed, just a URL. Create a webhook in your Discord channel settings and post to it with httpx.

Discord webhooks accept rich embeds, which look better than plain text. The embed format below produces a clean card with product details.

python
def post_to_discord(deals: list[Deal], webhook_url: str) -> None:
    """Post deals to a Discord channel via webhook."""
    for deal in deals:
        embed = {
            "title": f"Deal: {deal.name}",
            "url": deal.url,
            "color": 0x00FF00,  # Green
            "fields": [
                {"name": "Price", "value": f"{deal.currency} {deal.current_price:.2f}", "inline": True},
                {"name": "Target", "value": f"{deal.currency} {deal.threshold:.2f}", "inline": True},
                {"name": "Savings", "value": f"{deal.savings_pct}%", "inline": True},
            ],
        }
        httpx.post(webhook_url, json={"embeds": [embed]}, timeout=10.0)

# Usage with Discord
# post_to_discord(deals, os.environ["DISCORD_WEBHOOK_URL"])

Configuring Your Watchlist

The watchlist is a JSON file with products you want to monitor. Each entry has a URL, name, and target price. Add or remove products by editing this file — no code changes needed.

Start small with 5-10 products and expand as you get a feel for how often deals appear. Each product check costs one PriceFetch credit, so a watchlist of 20 products checked every 4 hours uses about 120 credits per day.

json
{
  "watchlist": [
    {
      "name": "Sony WH-1000XM5",
      "url": "https://www.amazon.com/dp/B0CHX3QBCH",
      "target_price": 278.00
    },
    {
      "name": "Anker 737 Power Bank",
      "url": "https://www.amazon.com/dp/B09VPHVT2Z",
      "target_price": 99.99
    }
  ]
}

Frequently asked questions

Start fetching prices — 500 free credits

Sign up in 30 seconds. No credit card required. One credit per successful API call.