I Built a Telegram Bot That Searches, Monitors Prices and Lets You Buy and Sell. Here's How

Published: (May 2, 2026 at 10:24 AM EDT)
3 min read
Source: Dev.to

Source: Dev.to

Most people check Jiji or Amazon manually every day waiting for a price to drop. I built a Telegram bot that does it for you automatically and also lets you list and sell items directly from Telegram.

No website. No app. Just Telegram.

GitHub:

What It Does

The bot has two sides.

For buyers: search for any product, set a target price, and get a Telegram alert the moment the price drops. It pulls real listings from Jiji Kenya and Google Shopping.

For sellers: list a product with a photo and description. Buyers can find it and contact you directly on Telegram.

The Architecture

The project is split into focused modules:

  • scraper.py — extracts prices from any product URL using BeautifulSoup
  • jiji.py — scrapes Jiji Kenya listings directly from their Nuxt data layer
  • search.py — queries Google Shopping via SerpAPI for any product in any country
  • telegram.py — sends price alert messages
  • bot_handler.py — handles all Telegram commands and conversation flows
  • scheduler.py — runs automatic price checks every 6 hours
  • listings.py — stores and retrieves local marketplace listings

The Jiji Scraper

Jiji loads listings with JavaScript, so a regular request returns empty content. The trick is that Jiji uses Nuxt.js, which embeds all the page data in a JSON script tag:

match = re.search(r'id="__NUXT_DATA__"[^>]*>(.*?)', res.text, re.DOTALL)
data = json.loads(match.group(1))

From there it is a matter of walking the data structure to extract titles, prices, locations, and URLs. The result is real Jiji listings without needing a headless browser.

The Conversation Flow

python-telegram-bot provides a ConversationHandler that manages multi‑step flows. The browse flow looks like this:

browse_handler = ConversationHandler(
    entry_points=[CommandHandler("browse", browse_start)],
    states={
        BROWSE_QUERY: [MessageHandler(filters.TEXT, browse_get_query)],
        BROWSE_MIN_PRICE: [MessageHandler(filters.TEXT, browse_min_price)],
        BROWSE_MAX_PRICE: [MessageHandler(filters.TEXT, browse_max_price)],
    },
    fallbacks=[CommandHandler("cancel", cancel)],
)

Each state waits for user input before moving to the next step. The user never has to type a command with arguments — the bot guides them through naturally.

Photo Support for Sellers

When a seller lists a product, they can send a photo. Telegram stores photos on its servers and returns a file_id. That ID is saved in the JSON config and later used to send the photo back to buyers:

if l.get("photo_id"):
    await update.message.reply_photo(photo=l["photo_id"], caption=caption)

No image hosting is needed; Telegram handles it all.

Automatic Price Monitoring

The scheduler runs every 6 hours using APScheduler. It checks all monitored URLs, compares current prices to targets, and fires Telegram alerts when a price drops:

scheduler.add_job(check_all, "interval", hours=interval_hours)

Start it once and forget about it.

What I Learned

  • Nuxt.js apps embed their data in script tags. Once you know where to look, scraping them is straightforward without Selenium or Playwright.
  • Telegram’s ConversationHandler is powerful but stateful. You have to manage session data carefully when multiple users are in different states at the same time.
  • Always send long results as individual messages. Telegram has a 4096‑character limit per message; a single long block will crash the handler silently.

What Is Next

  • WhatsApp integration
  • More marketplace sources beyond Jiji
  • Price history charts
  • Web dashboard to manage listings

Try It

GitHub:

0 views
Back to Blog

Related posts

Read more »