🇮🇳 IndianInSaudiArabia — Admin Dashboard
Single source of truth for all workflows, automations, and configurations. Last updated: July 2026.
📊 Site Overview
EN + HI
Bilingual (English + Hindi)
Tech Stack
| Layer | Technology |
|---|
| Framework | Astro v6 + Tailwind CSS v4 |
| Hosting | Vercel (auto-deploy from GitHub push) |
| OG Images | Satori (SVG→PNG) + Lucide icons |
| Search Index | Pagefind (static) |
| AI Model | zyloo/claude-sonnet-4-6 via Naraya Router |
| Repo | github.com/Anshad2u/indianinsaudiarabia (master) |
| Working Dir | /home/anshad/projects/indianinsaudiarabia |
📝 Content Pipeline
How Articles Are Created
1Research — Search priority: lifeinsaudiarabia.net → ksaexpats.com → saudi-expatriates.com. Cross-check official sources (gov.sa, SPA, ministry sites). Arabic Brave + ddgs for Arabic sources.
2Verify — Every claim checked against 2+ sources. License scope clarified honestly (e.g., PTSP ≠ banking license). If unsure, say so.
3Write EN — Non-robot tone, like an experienced friend. No YouTube references. SNB Neo affiliate link where relevant (snb-neo.onelink.me/vJWt/4l9iurx9).
4Write HI — Hindi version in src/data/post/hi/. Must have lang: "hi" in frontmatter (critical for i18n separation).
5OG Image — Run node generate_og.mjs <slug>. Lucide outline icons, light pastel bg, centred layout.
6Interlink — Add Related section, retro-link from existing hub guides. Use blog-index.json to find connections.
7Build + Push — npm run build → git push → Vercel auto-deploys.
Critical Rules
- EN file =
src/data/post/slug.md | HI file = src/data/post/hi/slug.md - HI files MUST have
lang: "hi" in frontmatter — otherwise they collide with EN - Every article needs
image: '/images/featured/slug.png' in frontmatter - One article at a time. No YouTube references.
- Research skill:
content/verified-news-article
🎨 OG Image System
Design: Light Background + Lucide Outline Icons
Light pastel bg per category, 200px lucide outline icon (stroke-based), centred title, category pill, subtitle, 3 tag pills.
node generate_og.mjs # all articles
node generate_og.mjs <slug> # single article
Category → Visual Mapping
| Category | BG | Accent | Icon |
|---|
| banking-money | #eef2ff | #3b5998 | banknote |
| absher-digital / absher | #e0f7fa | #00838f | shield |
| iqama-residency | #f3e5f5 | #6a1b9a | id-card |
| visa-family-visit | #fff3e0 | #e65100 | ticket |
| driving-traffic | #e8f5e9 | #2e7d32 | car |
| jobs-employment | #eceff1 | #37474f | briefcase |
| hajj-umrah | #e3f2fd | #1565c0 | moon |
| documents-embassy | #ede7f6 | #4527a0 | book-open |
| healthcare | #ffebee | #b71c1c | stethoscope |
| news | #e3f2fd | #1565c0 | newspaper |
Icons from lucide npm package — stroke-based, NOT filled. fill="none" stroke="${color}"
🐦 Twitter Signal Pipeline
Architecture
Twitter → collect_signals.py → gemini_triage → telegram_queue → YOUR APPROVAL → saudi-poster-converter
Topic-driven, curated accounts ONLY, keyword-filtered. Manual approval via Telegram bot. No auto-post.
12 User Topics
| # | Topic | Keywords | Need Image? |
|---|
| 1 | CareAljawazat useful updates | أبشر, خدمة, إصدار, تجديد | optional |
| 2 | Family visit visa news + MOI | Family Visit, تأشيرة زيارة, MOI | yes |
| 3 | Absher procedures | Absher, أبشر, iqama, إقامة | yes |
| 4 | eMAR traffic images | مرور, traffic, fine, مخالفة | yes |
| 5 | Saudi/India airlines offers | airline, flight, ticket, عرض | text+image |
| 6 | SPA + images | SPA, وكالة, official | yes |
| 7 | CBSE exams NRI | CBSE, exam, NRI, school | yes |
| 8 | Eid holidays official | Eid, عيد, holiday, إجازة | yes |
| 9 | Muharram/Islamic events | haramaininfo, Muharram, Islamic | yes |
| 10 | Hajj/Umrah updates | Hajj, Umrah, حج, عمرة, Nusuk | yes |
| 11 | Iqama news | iqama, إقامة, residency | yes |
| 12 | Other popular KSA accounts | general KSA, expat life | optional |
Curated Accounts (24+)
| Account | Category | Language |
|---|
| @AlJawazatKSA | Passports | Arabic |
| @CareAljawazat | Passport Support | Arabic |
| @Absher | Digital Services | Arabic |
| @eMAR_ksa | Traffic | Arabic |
| @KSAmofaEN | Foreign Affairs | English |
| @SaudiGazette | News | English |
| @Okaz_online | News | Arabic |
| @HaramainInfo | Islamic | English |
| @MOISaudiArabia | Interior Ministry | Arabic |
| ...and more | | |
How Collection Works
1Pull tweets — twitter user-posts <account> -n 5 --json via twitter_client.py
2Filter by topic — Match tweet text against TOPICS keywords in collect_signals.py
3Triage — Gemini vision (or manual) judges quality + relevance
4Queue to Telegram — Photo/text + topic label + ✅/❌ buttons
5Your approval — Approved items go to saudi-poster-converter for poster creation
# Files:
twitter-poster-signals/
collect_signals.py # main orchestrator
twitter_client.py # twitter CLI wrapper
gemini_triage.py # vision quality check
telegram_queue.py # approval bot
learn_accounts.py # account discovery
account_map.json # learned account data
Twitter Auth
Cookies in twitter-poster-signals/.env: TWITTER_AUTH_TOKEN + TWITTER_CT0. Re-login when cookies expire (every ~2 weeks).
⏰ Cron Jobs
| Name | Schedule | Script | Status |
|---|
| twitter-poster-signals | 06:00 UTC daily (09:00 KSA) | twitter_poster_signals.sh | Active |
| Daily News Collection | Was daily | Hermes cron c1aa260d | Disabled |
🔍 Research Workflow
Search Priority
| Priority | Source | Use For |
|---|
| 1st | lifeinsaudiarabia.net | Expat guides, procedures |
| 2nd | ksaexpats.com | Step-by-step guides |
| 3rd | saudi-expatriates.com | News, updates |
| Official | gov.sa, SPA, ministry sites | Fact verification |
| Arabic | Brave Arabic, ddgs | Arabic source verification |
Verification Rules
- Every claim checked against 2+ independent sources
- License scope stated honestly (e.g., PTSP ≠ banking license)
- If source says "reportedly" → we say "reportedly"
- Official sources linked inline with numbered references
- Disclaimer added when license scope is uncertain
🔗 Interlinking Strategy
How It Works
1blog_index.py generates blog-index.json — memory of all 156+ posts
2When writing new article, search blog-index for related posts
3Add "Related" section at bottom of new article linking to existing guides
4Retroactively add links FROM existing articles TO the new article
# Hub guides that link to many sub-articles:
absher-complete-guide → all Absher sub-articles
banking-money-guide → bank account, SAR to INR, etc.
iqama-residency-guide → iqama renewal, color status, etc.
driving-traffic-guide → license, fines, Fahas, etc.
🔐 Credentials & Config
| Service | Location | Notes |
|---|
| GitHub Token | ~/.git-indian-token | Format: https://Anshad2u:[TOKEN]@github.com/... |
| Gemini API | twitter-poster-signals/.env | Model: gemini-3-flash-preview |
| Telegram Bot | twitter-poster-signals/.env | Chat: 498691564 |
| Twitter Auth | twitter-poster-signals/.env | Re-login every ~2 weeks |
| SNB Neo Affiliate | Article frontmatter | snb-neo.onelink.me/vJWt/4l9iurx9 |
| AI Model | Hermes config | zyloo/claude-sonnet-4-6 via Naraya Router |
📋 Pending Tasks
| Task | Status |
|---|
| SPA.gov.sa faceless background images for OG | Planned |
| Run learn_accounts.py to expand account list | Planned |
| Phase 2: auto-post from approved queue | Future |
| Fix YouTube collector in cron (17/17 errors) | Broken |
| Apply silhouette to OG default.png | Planned |
📦 Git Conventions
# Commit message format:
Add: new article slug
Fix: description of fix
Enhance: what was improved
Rebuild: when regenerating assets
# Branch: master (auto-deploys to Vercel)
# Never push directly to main without build verification
Admin dashboard • Only accessible at /anshad • Password protected