DEV Community

BuyWhere
BuyWhere

Posted on

Build a Telegram Price-Comparison Bot with BuyWhere MCP

You built a Discord bot. You built a Slack bot. But your users live in Telegram โ€” especially in Southeast Asia, where Telegram is a primary messaging surface.

This post closes the series: a Telegram bot that takes any product query and replies with the best cross-market price, live.

What we're building

User: /best iPhone 17 Pro 256GB
Bot:  ๐Ÿ† Best: S$1,549 (SG, Lazada) โ€” verified seller
      ๐Ÿ“Š Cross-market: MY S$1,520 ยท TH S$1,598 ยท US S$1,499 +S$35 ship
      ๐Ÿ”— https://...
Enter fullscreen mode Exit fullscreen mode

~100 lines of Python. Runs on any VPS or Railway service.

Prerequisites

pip install buywhere-mcp python-telegram-bot
Enter fullscreen mode Exit fullscreen mode

Step 1 โ€” The handler

import os
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
from buywhere import MCPClient

client = MCPClient()  # BUYWHERE_API_KEY env var

async def best(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
    query = " ".join(ctx.args)
    if not query:
        await update.message.reply_text("Usage: /best <product query>")
        return

    results = client.search_products(
        query=query, markets=["SG", "MY", "TH", "US"], limit=3
    )
    if not results:
        await update.message.reply_text(f"No listings found for '{query}'.")
        return

    ranked = sorted(results, key=lambda r: r["price"] / r.get("fx", 1))
    top = ranked[0]
    await update.message.reply_text(
        f"๐Ÿ† Best: {top['price']} {top['currency']} ({top['market']})\n"
        f"๐Ÿ”— {top['url']}"
    )

app = ApplicationBuilder().token(os.environ["TELEGRAM_BOT_TOKEN"]).build()
app.add_handler(CommandHandler("best", best))
app.run_polling()
Enter fullscreen mode Exit fullscreen mode

Step 2 โ€” Cross-market table command

async def compare(update, ctx):
    query = " ".join(ctx.args)
    results = client.search_products(query=query, markets=["SG", "MY", "TH", "US"], limit=12)

    lines = []
    for market in ["SG", "MY", "TH", "US"]:
        mr = [r for r in results if r["market"] == market]
        if mr:
            low = min(mr, key=lambda r: r["price"])
            lines.append(f"{market}: {low['price']} {low['currency']}")

    await update.message.reply_text("\n".join(lines) or "No listings found.")

app.add_handler(CommandHandler("compare", compare))
Enter fullscreen mode Exit fullscreen mode

Step 3 โ€” Guard against stale prices

Every BuyWhere result carries price_updated_at. Skip listings older than 24h so your bot never quotes yesterday's price:

from datetime import datetime, timedelta, timezone

def fresh(r, max_hours=24):
    ts = datetime.fromisoformat(r["price_updated_at"].replace("Z", "+00:00"))
    return (datetime.now(timezone.utc) - ts) <= timedelta(hours=max_hours)

results = [r for r in results if fresh(r)]
Enter fullscreen mode Exit fullscreen mode

Deployment

Same pattern as the Slack bot: wrap in a systemd service or deploy to Railway, set BUYWHERE_API_KEY and TELEGRAM_BOT_TOKEN, and you're live. run_polling() needs no inbound webhook, so no domain or TLS setup required.

What's next

  • Inline query mode (type @yourbot iphone in any chat)
  • Price-watch subscriptions with the alert-engine pattern from the previous post
  • Group mode: anyone in a group chat can invoke /best

The full code is on GitHub. Link in comments.


This is part of the "BuyWhere MCP in practice" series. Previous posts covered
Discord shopping bots,
Slack deal-alert bots,
cross-border comparison,
and real-time price alerts.

Top comments (0)