https://github.com/codedpro/teleyab
Telegram username → phone-number lookup service (RTL). Pay only when we find a result. Wallet billing in Toman, card-to-card top-ups, Bearer-token API. Next.js 16 / React 19 / Tailwind v4 / Go 1.23 / Postgres 16.
https://github.com/codedpro/teleyab
ai-overviews chat-ui docker golang gsap llms-txt lookup-service nextjs osint phone-lookup postgres react rtl saas seo tailwindcss telegram typescript username-to-phone
Last synced: 9 days ago
JSON representation
Telegram username → phone-number lookup service (RTL). Pay only when we find a result. Wallet billing in Toman, card-to-card top-ups, Bearer-token API. Next.js 16 / React 19 / Tailwind v4 / Go 1.23 / Postgres 16.
- Host: GitHub
- URL: https://github.com/codedpro/teleyab
- Owner: codedpro
- Created: 2026-05-20T11:32:07.000Z (28 days ago)
- Default Branch: main
- Last Pushed: 2026-05-31T15:36:52.000Z (17 days ago)
- Last Synced: 2026-05-31T17:20:32.536Z (17 days ago)
- Topics: ai-overviews, chat-ui, docker, golang, gsap, llms-txt, lookup-service, nextjs, osint, phone-lookup, postgres, react, rtl, saas, seo, tailwindcss, telegram, typescript, username-to-phone
- Language: TypeScript
- Homepage: https://teleyab.ir
- Size: 182 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# TeleYab — Telegram Username → Phone Lookup
> RTL SaaS that turns a Telegram `@username` or numeric ID into the
> mobile phone number behind it. Wallet billing in Toman, card-to-card top-ups,
> pay-per-success model (failed lookups cost zero), Bearer-token API for
> developers, full admin operations dashboard.
>
> Built end-to-end as a monorepo: Next.js 16 / React 19 / Tailwind v4 web
> client + Go 1.23 / chi / pgx API + PostgreSQL 16, orchestrated with
> Docker Compose. RTL throughout, lazy-loaded GSAP motion,
> 14 JSON-LD schema blocks on the landing page, AI-Overview-friendly
> `llms.txt`, security headers, and structured per-page metadata.
#telegram · #osint · #lookup · #phone-lookup · #username-to-phone ·
#rtl · #nextjs · #react · #tailwindcss · #typescript · #golang ·
#postgres · #docker · #gsap · #chat-ui · #seo · #ai-overviews · #llms-txt · #saas
---
## Table of contents
- [What it does](#what-it-does)
- [Live screenshots](#live-screenshots)
- [Stack](#stack)
- [Repository layout](#repository-layout)
- [Run locally](#run-locally)
- [Environment](#environment)
- [API surface](#api-surface)
- [Pricing model](#pricing-model)
- [Referral program](#referral-program)
- [SEO + AI search](#seo--ai-search)
- [Design system](#design-system)
- [Performance](#performance)
- [Security](#security)
- [Contributing](#contributing)
- [License](#license)
---
## What it does
- **Single lookup** — paste an `@username` or numeric Telegram ID, get the phone number
plus (when available) name, email, previous usernames, birthday, country.
- **Batch lookup** — up to 500 rows per submission. Same per-row pricing.
Failures cost nothing.
- **Bearer-token API** — `POST /api/v1/lookup` with the same wallet billing.
curl-friendly, JSON in/out.
- **Wallet** — top up in Toman via card-to-card with an admin approval step.
Transparent ledger of every charge and credit.
- **Referrals** — both sides receive 200,000 Toman once the referred user's
**first top-up is approved**.
- **Admin** — operator dashboard for users, payments, refunds, abuse flags,
upstream providers, resellers, settings.
The product is positioned as **its own database** of Telegram identity
mappings. There is no live integration claim, no upstream-provider language
in user-facing copy, no marketing about Iranian customers (the audience is
inferred from the language and currency, not stated).
## Live screenshots
The home page uses a looping chat-style demo where the user sends an
`@username` and TeleYab "replies" with phone + email + previous usernames +
birthday — Telegram-flavoured bubbles, typing indicators, magnetic CTAs.
GSAP drives all scroll-revealed sections.
Run the stack locally (below) and visit:
- `/` — landing + live demo
- `/pricing` — live price + quick-charge presets (login-gated)
- `/lookup` — Telegram-chat composer (auth required)
- `/batch` — bulk upload
- `/keys` — API token issuance
- `/referral` — invite link + earnings
## Stack
| Piece | Tech | Port |
| ---------------- | ------------------------------------------------- | ---- |
| Web | Next.js 16, React 19, Tailwind v4, TypeScript | 4102 |
| Web motion | GSAP 3 + ScrollTrigger (lazy-loaded) | — |
| API | Go 1.23, chi router, pgx | 8084 |
| DB | PostgreSQL 16 (Alpine, in Docker) | 5436 |
| Auth | Email + password, magic-link verification | — |
| Payments | Card-to-card with admin approval | — |
| Sessions | Server-issued, HttpOnly cookies | — |
| Orchestration | Docker Compose | — |
Everything is wired via `docker compose up -d --build`.
## Repository layout
```
.
├── cmd/server/ # Go entrypoint
├── internal/
│ ├── config/ # env loading + first-run defaults
│ ├── db/ # pgx wrappers, schema.sql, seed
│ ├── handlers/ # chi route handlers (auth, lookup, admin, …)
│ ├── session/ # cookie + DB-backed sessions
│ └── …
├── web/
│ ├── app/ # Next.js 16 app router pages + routes
│ │ ├── (public) # /, /pricing, /privacy, /terms, /llms.txt, …
│ │ ├── (auth) # /login, /verify
│ │ ├── (dashboard) # /lookup, /batch, /keys, /wallet, /topup, /referral
│ │ └── admin/ # operator UI (8 pages)
│ ├── components/ # nav, footer, chat primitives, schema-ld, …
│ ├── lib/ # motion (lazy GSAP), cn, ref-capture, …
│ └── public/
├── docker-compose.yml
├── Dockerfile.api
├── go.mod
├── PLAN.md # architecture + roadmap
├── CLAUDE.md # operator guard-rails (token-burn warning, etc.)
└── README.md # this file
```
## Run locally
You need Docker + Docker Compose. **Do not run a fresh build against the
production upstream key** — see [CLAUDE.md](CLAUDE.md) for the token-burn
warning.
```bash
# clone
git clone https://github.com/codedpro/teleyab.git
cd teleyab
# copy env template + fill in secrets
cp .env.example .env
$EDITOR .env
# bring up everything (web on :4102, api on :8084, postgres on :5436)
docker compose up -d --build
# verify
curl -s http://127.0.0.1:4102/api/public/pricing
open http://127.0.0.1:4102
```
The first boot seeds default settings into the `settings` table:
- `price_per_lookup_toman` = `800000`
- `min_topup_toman` = `800000`
- `max_topup_toman` = `25000000`
- `referral_bonus_toman` = `200000`
Adjust live from the admin UI at `/admin/settings`. The first user to sign up
is automatically promoted to `admin` in the DB (or run
`UPDATE users SET role='admin' WHERE id=1;`).
## Environment
`.env.example` is the source of truth. Required keys, condensed:
| Key | Purpose |
| ------------------------- | -------------------------------------------------- |
| `DATABASE_URL` | Postgres DSN (`postgres://teleyab:teleyab@…`) |
| `WEB_ORIGIN` | Used to construct referral share URLs |
| `SESSION_COOKIE_DOMAIN` | Empty for local; set to root domain in prod |
| `RESEND_API_KEY` | Magic-link email delivery |
| `UPSTREAM_*` | Provider configuration (see PLAN.md §10) |
| `NEXT_PUBLIC_SITE_URL` | Canonical origin (web side) |
Never commit a real `.env` — it's in `.gitignore` and reading it counts as
exfiltration in the security policy.
## API surface
All routes mounted under `/api`. Authenticated routes require a session
cookie; the public Bearer route accepts `Authorization: Bearer `.
### Public
| Method | Path | Notes |
| ------ | ----------------------------- | ------------------------------------------- |
| GET | `/healthz` | Liveness probe |
| GET | `/public/pricing` | Live `price_per_lookup_toman`, min/max top-up, referral bonus |
### Auth
| Method | Path | Notes |
| ------ | --------------------- | ------------------------------------------- |
| POST | `/auth/register` | Email + password + optional `ref_code` |
| POST | `/auth/login` | Returns session cookie |
| POST | `/auth/verify-email` | Consumes verification token |
| POST | `/auth/logout` | |
### User (session required)
| Method | Path | Notes |
| ------ | ----------------------------- | ------------------------------------------- |
| GET | `/me` | Profile + balance + price |
| POST | `/lookup` | Web-side single lookup (`min_balance` gate) |
| GET | `/lookups` | History (no upstream call) |
| POST | `/topup/request` | Card-to-card submission with receipt |
| GET | `/topup/requests` | Own top-up history |
| GET | `/me/referral` | Own code, share URL, invited count, earned |
| POST | `/lookup/batch` | Up to 500 rows per submission |
| GET | `/lookup/batch/{id}` | Per-batch status + per-row results |
| GET | `/keys` / POST `/keys` | List / create Bearer tokens |
| DELETE | `/keys/{id}` | Revoke |
### Public Bearer API
| Method | Path | Notes |
| ------ | ---------------- | ------------------------------------------- |
| POST | `/v1/lookup` | Bearer-auth equivalent of web `/lookup` |
Example:
```bash
curl -X POST https://teleyab.ir/api/v1/lookup \
-H "Authorization: Bearer $TELEYAB_KEY" \
-H "Content-Type: application/json" \
-d '{ "query": "@arman_dev" }'
# → { "success": true,
# "numbers": ["+989124528521"],
# "country": "IR",
# "cost_toman": 800000,
# "balance_toman": 49200000 }
```
### Admin (role=admin)
`/admin/stats`, `/admin/users`, `/admin/users/{id}/{ban,unban,force-logout,adjust}`,
`/admin/refunds`, `/admin/refunds/{id}/{resolve,reject}`, `/admin/flags`,
`/admin/providers` (CRUD + toggle), `/admin/payments` (approve / reject),
`/admin/resellers`, `/admin/settings`, `/admin/upstream-balance`.
## Pricing model
- **Per successful lookup**: `settings.price_per_lookup_toman` (default 800,000 ﺗﻮﻣﺎن).
- **Failed lookup**: 0 Toman. No wallet debit.
- **Minimum top-up**: matches the per-lookup price (800,000 by default).
- **Currency**: Iranian Toman (IRT).
User-facing pages always read the live value from `/api/public/pricing` so the
admin can change pricing without redeploying.
## Referral program
- Friend signs up with `?ref=` or enters the code manually.
- `web/components/ref-capture.tsx` writes the code to `localStorage`
(30-day TTL) on any page load, then strips the query so URLs stay clean.
- `/login` falls back to that storage when its own `?ref=` is absent.
- Server attaches `users.referred_by` on the friend's first verified login.
- Bonus (200,000 Toman default) is credited to **both wallets** when the
friend's **first top-up is approved by an admin** — not on first lookup.
- Idempotent: `users.referral_bonus_paid` guards against double-pay.
- Defensive: skips payout if the referrer is `banned_at`, `flagged_at`,
or `is_active=false`.
## SEO + AI search
The site ships an aggressive on-page + technical SEO baseline:
- **`robots.txt`** — explicit allow for GPTBot, ClaudeBot, PerplexityBot,
Google-Extended, OAI-SearchBot, Applebot-Extended, Bingbot, CCBot,
cohere-ai, Meta-ExternalAgent; disallow on private routes (`/admin`,
`/wallet`, `/topup`, `/verify`, `/api`, `/login`).
- **`sitemap.xml`** — 8 public routes with realistic priorities + static lastmod.
- **`llms.txt` + `llms-full.txt`** — llmstxt.org format dump for AI Overviews,
Perplexity, ChatGPT, etc. Includes FAQ verbatim, full HowTo, prose
excerpts of privacy + terms.
- **`humans.txt`** — humanstxt.org credits.
- **`.well-known/security.txt`** — RFC 9116 contact.
- **`feed.xml`** — RSS 2.0 of the FAQ items.
- **JSON-LD** — Organization, WebSite (with SearchAction), Service,
WebApplication (with AggregateRating / Offer / UnitPriceSpecification),
BreadcrumbList, FAQPage, HowTo, SiteNavigationElement, WebPage
(TermsOfService / PrivacyPolicy variants). 14 distinct schema blocks on the
home page alone.
- **Security headers** — HSTS, COOP, X-Content-Type-Options, Referrer-Policy,
Permissions-Policy, baseline `X-Robots-Tag: index, follow,
max-image-preview:large, max-snippet:-1` with per-route `noindex,nofollow`
override on dashboard / auth / API.
- **Per-page metadata** — every public route exports its own title,
description, canonical, OG, and Twitter card.
## Design system
- **Palette** — Telegram-blue accent (`#229ED9`), light surface, jade success,
rose danger, saffron highlight. Variable names preserved
(`--color-persimmon`, `--color-bone`) for backward compatibility with the
pre-rebrand pages.
- **Typography** — Vazirmatn (two weights preloaded as woff2),
Inter (Latin sans), JetBrains Mono (code). Font-display: swap.
- **Components** — `t-card`, `t-btn`, `t-input`, `t-chip` primitives in
`globals.css`; chat primitives (`ChatBubble`, `ChatStream`, `ChatShell`,
`TypingDots`, `LiveChatDemo`) in `web/components/chat.tsx`.
- **Motion** — `web/lib/motion.tsx` exports `ScrollReveal`, `StaggerChildren`,
`CountUp`, `MagneticHover`, `ParallaxBlob`, `Typewriter`, `useGsap`,
`loadGsap`. GSAP is lazy-loaded — never in the critical client graph.
- **RTL** — `dir="rtl"` on ``, logical CSS properties
(`start`/`end`/`ps`/`pe`) used everywhere. Inputs that accept LTR data
(emails, card numbers, queries) wrap in `dir="ltr"` to keep icon
positioning and padding aligned.
## Performance
- GSAP + ScrollTrigger lazy-loaded behind a `loadGsap()` singleton —
`prefers-reduced-motion` users skip the import entirely.
- Vazirmatn Regular + Bold preloaded as woff2 (cuts one RTT on RTL copy).
- DNS prefetch + preconnect for all font hosts.
- `content-visibility: auto` on long sections; GPU promotion on animated blobs.
- Next.js standalone build behind a slim Alpine container.
## Security
- HttpOnly session cookies; CSRF surface minimised by same-site cookies +
origin-pinned sessions.
- Open-redirect defence: `/login?next=` validated to start with a single `/`.
- `maybeApplyReferralBonus` is transactional and idempotent.
- Admin routes gated by `users.role='admin'` + a session check.
- Receipt uploads stored under `/uploads/receipts/{filename}` with the
filename generated server-side from a timestamp + random hex.
- Token-burn guard: the `/api/lookup` and `/api/v1/lookup` paths cost real
upstream credits — see [CLAUDE.md](CLAUDE.md) for the operational rules.
## Contributing
This repository is currently maintained by a single operator
([@codedpro](https://github.com/codedpro)). Issues and PRs are welcome for
documentation fixes, accessibility regressions, RTL copy refinements,
and obvious bugs. Feature requests outside the
[non-goals section of PLAN.md](PLAN.md#2-what-this-is-not-deliberate-non-goals)
will likely be closed without comment.
Before opening a PR:
```bash
cd web && npm run typecheck # TypeScript strict
cd web && npm run build # Next.js production build
cd .. && go build ./... # Go API
```
## License
Proprietary. All rights reserved. Source is published for transparency and
self-hosting reference only; redistribution, commercial reuse, or
hosting a competing service without written permission is not licensed.
— TeleYab · ۱۴۰۵