No description
  • HTML 88.3%
  • TypeScript 11.6%
Find a file
2026-08-06 23:37:38 +06:00
.vscode chore: scaffold from typescript-template 2026-08-05 03:38:56 +06:00
scripts feat: add duckduckgo image provider 2026-08-05 03:46:44 +06:00
searxng fix: keep yandex web engine for shared network config 2026-08-06 23:37:38 +06:00
src fix: whitelist searxng engines and normalize protocol-relative image urls 2026-08-06 23:25:03 +06:00
.dockerignore chore: scaffold from typescript-template 2026-08-05 03:38:56 +06:00
.editorconfig chore: scaffold from typescript-template 2026-08-05 03:38:56 +06:00
.env.example fix: split searxng public url for telegram-reachable image proxy links 2026-08-06 22:40:11 +06:00
.gitignore chore: scaffold from typescript-template 2026-08-05 03:38:56 +06:00
AGENTS.md fix: address review findings 2026-08-05 04:31:26 +06:00
CLAUDE.md chore: scaffold from typescript-template 2026-08-05 03:38:56 +06:00
docker-compose.yml fix: split searxng public url for telegram-reachable image proxy links 2026-08-06 22:40:11 +06:00
Dockerfile chore: scaffold from typescript-template 2026-08-05 03:38:56 +06:00
eslint.config.mjs feat: add config loader and core types 2026-08-05 03:42:08 +06:00
package.json fix: address review findings 2026-08-05 04:31:26 +06:00
pnpm-lock.yaml fix: address review findings 2026-08-05 04:31:26 +06:00
pnpm-workspace.yaml chore: scaffold from typescript-template 2026-08-05 03:38:56 +06:00
README.md perf: hedge slow providers instead of waiting out their full timeout 2026-08-06 23:11:14 +06:00
tsconfig.json chore: scaffold from typescript-template 2026-08-05 03:38:56 +06:00

imager-bot

Telegram inline image-search bot. Type @yourbot cats in any chat to get a photo grid.

Sources

Tried in priority order; the first to return usable results wins. A provider still running after a 2s hedge delay no longer blocks the walk — the next one starts alongside it and whichever answers first wins. A provider with no configuration disables itself and is skipped. Per-provider durations are logged ([chain] name: N results in Xms) so slow sources are visible.

  1. SearXNG — self-hosted metasearch, fans out to Google, Bing, DuckDuckGo and Yandex Images at once. Also proxies every image so Telegram can fetch it.
  2. Brave Images API — optional, set BRAVE_API_KEY.
  3. DuckDuckGo — no key required.
  4. Yandex Images — last resort, HTML scrape.

Quick start

cp .env.example .env
echo "SEARXNG_SECRET=$(openssl rand -hex 32)" >> .env
# put your @BotFather token in BOT_TOKEN
docker compose up -d

Then send /setinline to @BotFather and pick this bot so inline mode is enabled.

Local development

pnpm install
docker compose up -d searxng
pnpm dev

Configuration

Variable Required Default Purpose
BOT_TOKEN yes @BotFather token
SAFESEARCH no strict strict, moderate, or off
SEARXNG_URL no internal API origin, enables the SearXNG provider
SEARXNG_PUBLIC_URL no SEARXNG_URL public origin for image-proxy links — must be reachable by Telegram's servers or inline results fail with WEBDOCUMENT_URL_INVALID
SEARXNG_SECRET no must match SearXNG's server.secret_key
BRAVE_API_KEY no enables the Brave provider

SEARXNG_URL and SEARXNG_SECRET must both be set for SearXNG to activate.

Commands

  • pnpm dev — watch mode
  • pnpm start — production run
  • pnpm test — run tests
  • pnpm lint:fix — lint and auto-fix

Notes

Scraped providers (DuckDuckGo, Yandex) use undocumented endpoints and will break when those change. The recorded fixtures under src/providers/__fixtures__/ are what turn that breakage into a failing test — re-record them when a provider starts returning nothing.