We filter the noise to bring you the core of AI evolution.
Sharp analysis, organic design, zero filler.
Features • Architecture • Installation • Deployment • Usage • Cost
LensAI is an AI-powered tech news aggregator that delivers personalized daily digests via Telegram. It scrapes top tech sources, summarizes them with AI, and sends you the most important stories — so you never miss what matters in AI and tech.
- 📰 Multi-source aggregation — Hacker News, TechCrunch, AI company blogs, The Verge, GitHub Trending
- 🤖 AI summarization — DeepSeek creates digestible, curated digests
- 🔖 Article saving — Save interesting articles to your personal collection
- 💬 Q&A Chat — Ask any tech question and get AI-powered answers
- ⏰ Scheduled delivery — Set your preferred daily digest time
- 🌐 Multi-language — Full support for English, Russian, and Azerbaijani
- ☁️ Cloud-native — Runs 24/7 on Google Cloud Functions with Firestore
| Feature | Description |
|---|---|
| 📰 News Scraping | Fetches from Hacker News, TechCrunch, AI blogs (Anthropic, OpenAI, Mistral, DeepMind), The Verge, GitHub Trending |
| 🧠 AI Summarization | Uses DeepSeek to create engaging, categorized news digests |
| 🛡️ AI Fallback | 3-tier degradation: AI → Simple digest → Raw list (never fails!) |
| 🔄 Retry Logic | All scrapers retry 2x with exponential backoff for resilience |
| 📨 Smart Message Splitting | UTF-8 safe splitting at natural boundaries (no emoji corruption) |
| 🔖 Save Articles | Save articles to Firestore with automatic categorization (AI, Security, Crypto, etc.) |
| 📂 Filter & Recap | Filter saved articles by category, get weekly recaps |
| 💬 Interactive Q&A | Ask questions about any tech topic and get AI responses |
| ⚡ Smart Caching | 15-minute cache prevents redundant API calls |
| 🔒 Distributed Lock | Firestore-based locking prevents duplicate message sends |
| 🎛️ Source Control | Toggle news sources on/off via inline buttons |
| ⏰ Custom Scheduling | Set your preferred daily digest delivery time |
| 🌐 Multi-language | English, Russian, and Azerbaijani support |
┌──────────────────────────────────────────────────────────┐
│ GOOGLE CLOUD │
├──────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Cloud │───▶│ Cloud │ │
│ │ Scheduler │ │ Functions │ │
│ │ (your time) │ │ (Python 3.11)│ │
│ └──────────────┘ └──────┬───────┘ │
│ │ │
│ ┌──────────────┐ │ ┌──────────────┐ │
│ │ Firestore │◀─────────┼─────▶│ Telegram │ │
│ │ Database │ │ │ Bot API │ │
│ │ • Users │ │ └──────┬───────┘ │
│ │ • Articles │ │ │ │
│ │ • Locks │ │ │ │
│ └──────────────┘ │ │ │
│ │ │ │
│ ┌──────────────┐ │ │ │
│ │ Secret │◀─────────┘ │ │
│ │ Manager │ │ │
│ └──────────────┘ │ │
│ │ │
└──────────────────────────────────────────┼─────────────┘
│
┌─────────────────────────────────┘
│
┌────┴──────┐ ┌──────────────┐
│ News │ │ YOU │
│ Sources │ │ (Telegram) │
│ • HN │ └──────────────┘
│ • TC │
│ • AI │
│ • Verge │
│ • GitHub │
└───────────┘
LensAI/
├── functions/ # Cloud Functions code
│ ├── main.py # HTTP endpoints
│ ├── telegram_bot.py # Bot commands & handlers
│ ├── summarizer.py # DeepSeek AI integration
│ ├── resilience.py # Retry & backoff utilities (NEW)
│ ├── fallback_digest.py # Non-AI digest generator (NEW)
│ ├── message_utils.py # Smart message splitting (NEW)
│ ├── cache.py # In-memory caching
│ ├── database.py # Firestore operations
│ ├── distributed_lock.py # Distributed locking
│ ├── scrapers/
│ │ ├── hackernews.py # Hacker News API
│ │ ├── techcrunch.py # TechCrunch RSS
│ │ ├── ai_blogs.py # AI company blogs
│ │ ├── theverge.py # The Verge RSS
│ │ └── github_trending.py # GitHub trending repos
│ └── requirements.txt
├── run_local.py # Local development runner
├── test_scrapers.py # Scraper tests
├── .env.example # Environment template
├── .gitignore # Security exclusions
├── logo.jpg # Project logo
└── README.md # This file
- Python 3.11+
- Google Cloud CLI (for deployment)
- Telegram account
- DeepSeek API key (Get one here)
# Clone the repository
git clone https://github.com/YOUR_USERNAME/LensAI.git
cd LensAI
# Create virtual environment
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # macOS/Linux
# Install dependencies
pip install -r functions/requirements.txt python-dotenv
# Set up environment variables
cp .env.example .env
# Edit .env with your API keys
# Run locally
python run_local.py# 1. Login to Google Cloud
gcloud auth login
# 2. Set your project
gcloud config set project YOUR_PROJECT_ID
# 3. Enable required APIs
gcloud services enable cloudfunctions.googleapis.com cloudbuild.googleapis.com run.googleapis.com secretmanager.googleapis.com
# 4. Store secrets
gcloud secrets create TELEGRAM_BOT_TOKEN --replication-policy="automatic"
echo "YOUR_TOKEN" | gcloud secrets versions add TELEGRAM_BOT_TOKEN --data-file=-
gcloud secrets create DEEPSEEK_API_KEY --replication-policy="automatic"
echo "YOUR_KEY" | gcloud secrets versions add DEEPSEEK_API_KEY --data-file=-
# 5. Grant permissions
gcloud secrets add-iam-policy-binding TELEGRAM_BOT_TOKEN \
--member="serviceAccount:YOUR_PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
gcloud secrets add-iam-policy-binding DEEPSEEK_API_KEY \
--member="serviceAccount:YOUR_PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
# 6. Deploy function
gcloud functions deploy telegram_webhook \
--gen2 \
--runtime=python311 \
--region=europe-west1 \
--source=functions \
--entry-point=telegram_webhook \
--trigger-http \
--allow-unauthenticated \
--set-secrets="TELEGRAM_BOT_TOKEN=TELEGRAM_BOT_TOKEN:latest,DEEPSEEK_API_KEY=DEEPSEEK_API_KEY:latest" \
--memory=512MB \
--timeout=300s
# 7. Set Telegram webhook
curl "https://api.telegram.org/botYOUR_TOKEN/setWebhook?url=YOUR_FUNCTION_URL"| Command | Description |
|---|---|
/start |
Welcome message with quick action buttons |
/news |
Get your personalized news digest |
/settime HH:MM |
Set daily digest time (24h format) |
/sources |
Toggle news sources on/off |
/status |
View your current settings |
/help |
Show all commands |
| Any text | Ask a question — AI will answer! |
The bot provides persistent keyboard buttons for fast access:
- 📰 Get News — Fetch latest digest
- ⚙️ Settings — Manage sources
- 📊 Status — View settings
- ❓ Help — Show help
LensAI is designed to be extremely cost-effective:
| Service | Monthly Cost |
|---|---|
| DeepSeek API | ~$1-3 |
| Google Cloud Functions | Free tier (2M invocations) |
| Secret Manager | Free tier |
| Total | ~$1-5/month |
- ✅ API keys stored in Google Cloud Secret Manager
- ✅
.envfiles excluded from version control - ✅ No hardcoded credentials in source code
- ✅ HTTPS-only webhook communication
LensAI is production-ready with:
- ✅ Auto-scaling via Cloud Functions (0 to 6 instances)
- ✅ Secrets management via Google Secret Manager
- ✅ Distributed locking to prevent race conditions
- ✅ Retry logic with exponential backoff
- ✅ AI fallback for 100% uptime
- ✅ Smart caching to reduce costs
# Set up Cloud Monitoring alerts
gcloud alpha monitoring policies create \
--notification-channels=YOUR_CHANNEL_ID \
--display-name="LensAI Function Errors" \
--condition-display-name="Error rate \u003e 5%" \
--condition-threshold-value=0.05 \
--condition-threshold-duration=300sWhat to monitor:
- Function error rate
- Function execution time
- DeepSeek API latency
- Scraper success/failure rates
- Message queue length
# Already implemented in code:
print(f"⚠️ {function_name} attempt {retry} failed") # Retry logs
print(f"AI summarization failed: {e}") # Fallback logsView logs:
gcloud functions logs read telegram_webhook --region=europe-west1Current optimizations:
- 15-min cache reduces API calls
- Smart message splitting prevents rate limits
- Retry logic prevents wasted invocations
Additional recommendations:
- Set up billing alerts at $5, $10, $20
- Monitor DeepSeek API usage
- Consider caching scraper results for 30min
Firestore backups:
# Enable automatic backups
gcloud firestore backups schedules create \
--database='(default)' \
--recurrence=weekly \
--retention=4wSecret rotation:
# Rotate API keys every 90 days
gcloud secrets versions add DEEPSEEK_API_KEY --data-file=new_key.txtRecommended GitHub Actions workflow:
name: Deploy to GCP
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: google-github-actions/setup-gcloud@v1
- run: |
gcloud functions deploy telegram_webhook \
--gen2 --runtime=python311 ...Set up health endpoint:
# Test function health
curl https://YOUR_FUNCTION_URL/healthResponse:
{
"status": "healthy",
"timestamp": "2025-12-26T11:50:00Z"
}| Metric | Target | Current |
|---|---|---|
| Function cold start | \u003c 3s | ~2s |
| Digest generation | \u003c 60s | ~30-45s |
| Message delivery | \u003c 5s | ~2-3s |
| Scraper success rate | \u003e 95% | ~98% |
| AI fallback rate | \u003c 5% | ~1-2% |
- Language: Python 3.11
- Bot Framework: python-telegram-bot
- AI: DeepSeek API (OpenAI-compatible)
- Cloud: Google Cloud Functions (Gen 2)
- Scraping: httpx, BeautifulSoup, feedparser
MIT License — feel free to use, modify, and distribute.
Contributions are welcome! Please feel free to submit a Pull Request.
Made with ❤️ by Amin Sobor
