Monitor prices with PriceFetch API, detect deals based on configurable thresholds, and post them to Telegram or Discord channels automatically.
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 FreeCreate 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`)
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"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.
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 dealsThe 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.
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()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.
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"])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.
{
"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
}
]
}Sign up in 30 seconds. No credit card required. One credit per successful API call.