A Discord bot that drops you into a random street view from anywhere in the world. Guess the country, compete with friends, climb the leaderboard.
- Someone types
/geo - The bot fetches a random street-level image from Mapillary
- Everyone in the channel guesses which country it is
- 3 tries per player — typos are forgiven, aliases work (USA, UK, Holland...)
- Use
/hintif you're stuck — it reveals the continent, then the first letter, then the word length - First to guess correctly wins. If everyone fails, the answer is revealed automatically
| Command | Description |
|---|---|
/geo |
Start a new round |
/hint |
Get a progressive hint (continent → first letter → letter count) |
/skip |
Skip the round and reveal the answer |
/leaderboard |
Top 10 players by wins |
/stats |
Your stats or another player's |
/lang |
Switch language (English / French) |
/help |
How to play |
- Fuzzy matching — "Frnace" → France, "espana" → Spain, "uk" → United Kingdom
- Multiplayer — Multiple players guess simultaneously, answer only revealed when all are out of tries
- Leaderboard — SQLite-backed persistent stats with win streaks
- Bilingual — Full English and French support, persisted per server
- Hint system — 3 progressive hints per round
- Crash-resistant — All API calls wrapped with timeouts and error handling
| Component | Technology |
|---|---|
| Runtime | TypeScript + Node.js |
| Discord | discord.js v14 |
| Street imagery | Mapillary API v4 (free) |
| Geocoding | Nominatim / OpenStreetMap (free) |
| Database | SQLite via better-sqlite3 |
| Fuzzy matching | Fuse.js |
- Node.js 18+
- A Discord bot application with Message Content Intent enabled
- A Mapillary API token (free)
git clone https://github.com/your-username/geoguessr-npmz-discord-bot.git
cd geoguessr-npmz-discord-bot
npm installCopy the example env file and fill in your tokens:
cp .env.example .envDISCORD_TOKEN=your_discord_bot_token
DISCORD_CLIENT_ID=your_discord_application_id
MAPILLARY_TOKEN=your_mapillary_client_access_token# Development (with hot reload via tsx)
npm run dev
# Production
npm run build
npm startReplace YOUR_CLIENT_ID with your Discord application ID:
https://discord.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&permissions=277025508352&scope=bot%20applications.commands
# Copy the service file
sudo cp deploy/geoguessr-bot.service /etc/systemd/system/
# Edit the service file with your paths and user
sudo nano /etc/systemd/system/geoguessr-bot.service
# Enable and start
sudo systemctl enable geoguessr-bot
sudo systemctl start geoguessr-bot
# Check status
sudo systemctl status geoguessr-bot
# View logs
journalctl -u geoguessr-bot -fThe included deploy/update.sh script pulls the latest code and restarts the bot:
# Set up a cron job to check for updates every 5 minutes
crontab -e
# Add: */5 * * * * /path/to/geoguessr-npmz-discord-bot/deploy/update.shOr use a GitHub webhook for instant deploys.
src/
├── commands/ # Slash command handlers
│ ├── geo.ts # /geo — start a round
│ ├── hint.ts # /hint — progressive hints
│ ├── skip.ts # /skip — skip round
│ ├── leaderboard.ts
│ ├── stats.ts
│ ├── help.ts
│ └── lang.ts # /lang — switch language
├── services/ # External API clients
│ ├── mapillary.ts # Street view image fetching
│ ├── geocoding.ts # Reverse geocoding (Nominatim)
│ ├── location.ts # Random coordinate generation
│ └── leaderboard.ts # SQLite persistence
├── game/ # Game state management
│ ├── session.ts # Round state & player tracking
│ ├── manager.ts # Active sessions per channel
│ └── matcher.ts # Fuzzy country name matching
├── data/
│ ├── countries.ts # 130+ countries with bboxes, flags, aliases
│ └── continents.ts # Country → continent mapping
├── i18n.ts # English & French translations
├── config.ts # Environment variable loading
└── index.ts # Bot entry point & message handler
- Street-level imagery by Mapillary (Meta)
- Geocoding by OpenStreetMap / Nominatim
- Inspired by GeoGuessr
MIT — do whatever you want with it.
Built by Maxime Mansiet as a fun side project.
