Telegram agent
B2B Enricher
A Telegram bot that turns a company name or domain into a structured list of decision-makers - names, titles, LinkedIn, verified emails, and phone numbers - with the source of every field recorded.
01
Setup status
What the running service can reach right now. Booleans only - credentials are never shown.
At least one enrichment provider (Hunter or Apollo) is required. If neither is configured, the bot still answers but returns no people.
02
Data flow
From a chat message to a provenance-backed record, in six steps.
Message
A Telegram user sends /enrich acme.com cto or just types a company.
Normalize
Company names and URLs are cleaned into a domain and an optional role filter.
Discover
Apollo returns people; Hunter returns domain emails. Responses are cached and audited.
Verify
Hunter checks each email. Unfound emails may be guessed from a pattern - clearly marked.
Shape
Fields are merged into one record with per-field provider and timestamp provenance.
Deliver
The bot replies with text, or sends a JSON / CSV file attachment.
03
Telegram commands
Type a company name or domain as a plain message and it is treated as an enrich request.
/startWelcome message/helpUsage and examples/commandsList of commands/statusWhich providers are configured/enrich <company> [role]Run enrichment, reply with text/export <company> [role] [json|csv]Send a JSON or CSV file/exportjson <company> [role]Send a JSON file/exportcsv <company> [role]Send a CSV fileExamples
/enrich acme.com /enrich acme.com cto /enrich "Acme Inc" head of marketing /export acme.com cfo csv
04
Output schema
Every value carries its provider and retrieval timestamp. Emails are clearly marked.
{
"company": "Acme Inc",
"domain": "acme.com",
"role_filter": "cto",
"generated_at": "2026-01-01T00:00:00Z",
"providers_used": ["apollo", "hunter"],
"people": [
{
"full_name": "Jane Doe",
"title": "Chief Technology Officer",
"company": "Acme Inc",
"linkedin_url": "https://linkedin.com/in/jane",
"email": {
"address": "jane@acme.com",
"status": "verified",
"sources": [
{ "field": "email", "provider": "hunter",
"retrieved_at": "2026-01-01T00:00:00Z" }
]
},
"phone": {
"number": "+1 555 0100",
"source": "apollo",
"sources": [
{ "field": "phone", "provider": "apollo",
"retrieved_at": "2026-01-01T00:00:00Z" }
]
}
}
]
}Email status
verified Hunter confirmed the mailbox is deliverable.
unverified Hunter could not confirm it (invalid, disposable, or unknown).
guessed Built from a name pattern (first.last@domain), never confirmed. Treat as a lead to validate.
05
Deployment
The service is a Python app in service/. It runs locally, in Docker, or behind a webhook.
Local
cd service python3 -m venv .venv && source .venv/bin/activate pip install -r requirements.txt cp .env.example .env # fill in your keys python main.py init-db python main.py telegram # long-polling
Docker
cd service cp .env.example .env # fill in your keys docker compose up -d --build
Environment
HUNTER_API_KEYHunter.io API keyAPOLLO_API_KEYApollo.io API keyTELEGRAM_BOT_TOKENToken from @BotFatherB2B_TELEGRAM_ALLOWED_USER_IDSOptional allowlist of user IDsB2B_TELEGRAM_MODEpolling or webhookB2B_DB_PATHSQLite cache + audit database pathB2B_RATE_LIMIT_PER_MINUTEProvider calls per minuteB2B_MAX_PEOPLEMax decision-makers per queryFull setup, webhook notes, and troubleshooting live in service/README.md.
06
Security & privacy
Built to be safe in production - and honest about what enrichment data is.
Keys stay server-side
API keys are read from the environment only and are redacted from the audit log before anything is written to disk.
Field-level provenance
Every value records which provider supplied it and when, so data can be traced and refreshed.
Allowlist the bot
Restrict who can trigger enrichment (which spends your paid API quota) with an allowlist of Telegram user IDs.
Enrichment data is personal data
Names, work emails, and phone numbers are subject to GDPR, CCPA, and anti-spam rules. Have a lawful basis, keep data accurate, honor deletion requests, and never use it for spam.